C++;模板静态成员实例化 #包括 #包括 模板 甲级 { 静态std::地图数据; 公众: () { STD::CUT< P>我没有VisualC++操作,但是我可以看到与GCC编译的代码相同的问题。需要初始化数据成员: std::cout << data.size() << std::endl; template std::map A::data=std::map();
通过此更改,它可以正确编译和运行(对于我来说,在Linux上的GCC上)。代码中没有显式实例化 在其他静态数据成员中,没有实例化静态数据成员的初始化顺序。因此,您的代码实际上具有未定义的行为:根据编译器是首先初始化映射还是C++;模板静态成员实例化 #包括 #包括 模板 甲级 { 静态std::地图数据; 公众: () { STD::CUT< P>我没有VisualC++操作,但是我可以看到与GCC编译的代码相同的问题。需要初始化数据成员: std::cout << data.size() << std::endl; template std::map A::data=std::map();,c++,templates,static,instantiation,member,C++,Templates,Static,Instantiation,Member,通过此更改,它可以正确编译和运行(对于我来说,在Linux上的GCC上)。代码中没有显式实例化 在其他静态数据成员中,没有实例化静态数据成员的初始化顺序。因此,您的代码实际上具有未定义的行为:根据编译器是首先初始化映射还是a,对映射的引用是否有效 请参阅。该代码中有几个错误。首先,最初的想法不好。您有两个全局静态对象:a和a::data。它们的初始化顺序未定义。根据编译器的情绪,您有50%的机会首先调用a的构造函数并尝试将某些内容写入未初始化的A::data 这有时被称为问题。建议的解决方案是通
a
,对映射的引用是否有效
请参阅。该代码中有几个错误。首先,最初的想法不好。您有两个全局静态对象:
a
和a::data
。它们的初始化顺序未定义。根据编译器的情绪,您有50%的机会首先调用a
的构造函数并尝试将某些内容写入未初始化的A::data
这有时被称为问题。建议的解决方案是通过将这些对象移动到函数中,将其转化为局部静态对象:
template<> std::map<int, int> A<char>::data = std::map<int, int>();
#包括
#包括
模板
甲级
{
标准::地图和数据()
{
静态std::map d;
返回d;
}
公众:
()
{
std::cout什么编译器?我不认为这是你的错。使用VS2010可以很好地编译。我使用的是vs2008,它确实可以编译,但程序在行数据[3]处中断4@mrs:啊,我没有仔细查看您的代码。您无法访问数据[3]
直到向量
的大小至少调整为4
数据。另一方面,push_back(4)
会增加数据的大小
并初始化新元素。因此,如果它在任何情况下在更改为数据后都能正常工作,则push_back()
,那么编译器毕竟没有问题。@Potatoswatter容器是一个映射,而不是一个向量;不需要调整大小。这是因为每个用不同类型初始化的模板都需要一个单独的数据实例吗?在这个例子中,charI尝试std::vector而不是map,并且在没有显式ins的情况下一切正常tantiation-你认为这只是运气吗?有趣的是,在本例中,构造函数std::cout中的第一行是“显式实例化”不是显式实例化。它是名为data
的静态数据成员的定义,它是T=char
的模板a
的显式专门化的定义。没有这种显式专门化。编译器必须为该代码发出错误消息(如果您在中对其进行注释)。
std::cout << data.size() << std::endl;
template<> std::map<int, int> A<char>::data = std::map<int, int>();
#include <map>
#include <iostream>
template <typename T>
class A
{
std::map<int, int> &data()
{
static std::map<int, int> d;
return d;
}
public:
A()
{
std::cout << data().size() << std::endl;
data()[3] = 4;
}
};
int main()
{
A<char> a;
return 0;
}