C++类模板的静态成员变量的初始化,怎么回事呢?

刘地 发布于 2013/05/24 19:44
阅读 3K+
收藏 0

我喜欢使用静态成员变量配合构造函数来实现数据初始化,但是这个用在类模板上就出现了问题。

简化后,代码如下:

#include <stdio.h>

struct A
{
	A(){}
	A(void (*p)()){p();}
};

struct B
{
	static int i;
	static A   a;
	static void f()
	{
		i=1;
	}
};
int B::i=0;
A   B::a(B::f);

template <typename T>
struct C
{
	static int i;
	static A   a;
	static void f()
	{
		i=1;
	}
};
template <typename T>
int C<T>::i=0;
template <typename T>
A   C<T>::a(C<T>::f);

int main()
{
	printf("B::i=%d\n",B::i);
	printf("C::i=%d\n",C<char>::i);
	return 0;
}

/*************************
B::i=1
C::i=0
*************************/

本以为两个都应该输出1的。

求教是怎么回事,有什么办法作为合适的替代么?

加载中
0
rxaa
rxaa

模板只有在带入实参实例化后才会具现相应的代码

所以你的代码只有C<char>::i被初始化

可以对a以特化的方式来完成初始化

template <>
A   C<char>::a(C<char>::f);




0
刘地
刘地

引用来自“rxaa”的答案

模板只有在带入实参实例化后才会具现相应的代码

所以你的代码只有C<char>::i被初始化

可以对a以特化的方式来完成初始化

template <>
A   C<char>::a(C<char>::f);




但是很显然的是,我们不能让不知情的使用者每次特化都这么来吧?所以求法门
0
rxaa
rxaa

引用来自“刘地”的答案

引用来自“rxaa”的答案

模板只有在带入实参实例化后才会具现相应的代码

所以你的代码只有C<char>::i被初始化

可以对a以特化的方式来完成初始化

template <>
A   C<char>::a(C<char>::f);




但是很显然的是,我们不能让不知情的使用者每次特化都这么来吧?所以求法门

这个对所有的模板参数特化行为不是因该在你写库时就进行的么?

对静态成员我一般都是考虑单例模式,不然还会遇到初始化顺序问题

rxaa
rxaa
另外应为模板不支持分离编译,想在其他编译单元中引用的话,代码就只能都写在头文件中,但是在头文件中初始化静态成员会造成多重定义问题(可用编译器扩展GCC:__attribute__((weak))或MSVC:__declspec(selectany)来解决),使用单例模式可以标准c++的方式解决此问题
0
感冒九十九
感冒九十九
很显然,上面的解释是正确的
0
c
canghua

在main前面加个explicit实例化

template struct C<char>;

但是使用explicit实例化需要小心。

返回顶部
顶部