给予:
template<class T>
struct S {
static int const N = 1;
};
extern template class S<int>;
template<class T>
int f( T n ) {
return n + S<T>::N; // line 10
}
int main() {
return f(1); // line 14
}
//template class S<int>; // intentionally commented out to trigger error我得到:
foo.cpp: In function ‘int f(T) [with T = int]’:
foo.cpp:10: instantiated from ‘const int S<int>::N’
foo.cpp:10: instantiated from ‘int f(T) [with T = int]’
foo.cpp:14: instantiated from here
foo.cpp:10: error: explicit instantiation of ‘S<int>::N’ but no definition available但是为什么我会得到错误呢?
S<T>::N.。
这是MacOSX10.6.6上的g++ 4.2.1版。
发布于 2011-02-17 18:08:22
extern template class S<int>;我认为这一行会导致错误,因为它告诉编译器在某个地方查找S<int>的显式实例化,但不存在显式实例化。因此出现了错误。
一旦您注释了这一行,我认为代码应该编译得很好。
编辑:
好吧,看这个:http://www.ideone.com/oQnOi
就像我说的,它编译得很好!
编辑:
我认为$9.4.2/4 (由Mark B引用)不适用于类模板的静态成员,因为$14.5.1.3 temp.static不要求在命名空间范围内定义静态成员:
静态数据成员的定义可以在包含静态成员的类模板的名称空间范围内提供。
下面的例子如下:
template<class T> class X { static T s; };
template<class T> T X<T>::s = 0;注意,它并没有说“必须提供”,而是“可以提供”。因此,我认为在命名空间范围内定义类模板的静态成员是可选的。
发布于 2011-02-17 18:10:04
从9.4.2/2:
静态数据成员在其类定义中的声明不是定义,可能是不完整的类型,而不是of限定的空。静态数据成员的定义应出现在包含成员类定义的命名空间范围中。在命名空间范围的定义中,静态数据成员的名称应使用::操作符按其类名限定。
从9.4.2/4开始:
如果一个静态数据成员是const积分或const枚举类型,则它在类定义中的声明可以指定一个常量初始化器,它应该是一个积分常量表达式(5.19)。在这种情况下,成员可以在其范围内以积分常量表达式出现。如果名称空间作用域在程序中使用,则仍应在名称空间范围中定义成员,并且命名空间范围定义不应包含初始化器。
从这些引用中我们可以推断出("...shall仍被定义为.“)在9.4.2/4中,如果没有定义程序,那么程序就不是格式良好的程序。
https://stackoverflow.com/questions/5032683
复制相似问题