2017-05-21 75 views
0
#include <iostream>                            
#include <string>                             

using namespace std;                            

template <typename T,                            
      typename T::type N,                          
      typename T::strata& X>                         
struct SomeClass{};                            

struct S1                               
{                                 
    typedef int type;                            
    typedef string strata;                           
};                                 

int main() {                              
    SomeClass<S1, 3, string("erg")> x;                        
}  

失败消息:非类型模板参数没有引用任何声明?

g++ templ.cc -o templ -std=c++14                     
templ.cc:18:20: error: non-type template argument does not refer to any declaration            
    SomeClass<S1, 3, string("erg")> x;                        
        ^~~~~~~~~~~~~                         
templ.cc:8:24: note: template parameter is declared here                   
      typename T::strata& X> 

为什么它的工作原理为INT而不是字符串? 为什么它说该字符串是非类型的参数?

+0

因为它不是一个类型。非类型参数仅限于基元(实际上,积分和指针) –

+2

@PasserBy也可以使用此处所用的类类型引用。 – aschepler

+0

而且...我没有看到那个参考:) –

回答

4

模板参数是一个值,而不是一个类型或模板,简单地称为“非类型模板参数”。

由于参考文献而失败。如果您有typename T::type& N,您会在3上看到类似的错误。

引述cppreference.com

以下限制实例具有非类型模板参数模板时适用:

  • 对于左值参考的参数,在实例中提供的参数不能是暂时的,一个未命名的左值或一个没有链接的命名左值(换句话说,参数必须有链接)。

所以你的临时无效。但你可以这样做:

std::string erg("erg"); 
int main() {                              
    SomeClass<S1, 3, erg> x;                        
} 
+0

为什么如果我在main()中放入字符串,它会抱怨“没有链接”? –

+4

由于具有自动存储持续时间的变量没有链接。 – aschepler