gpt4 book ai didi

c++ - 除非明确专门化,否则模板类的静态成员不会实例化?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:25:57 25 4
gpt4 key购买 nike

我有一个模板单例类,带有一个静态实例和一个静态 getInstance() 方法。但是,我在 g++ (MinGW) 的实例上收到 undefined reference 错误;起初,我认为这是链接器顺序错误,但无论我将它们放入哪个顺序,我都会得到同样的结果。

但是,我发现如果我显式特化该实例,它确实可以编译(这不是一个可接受的解决方案)。所以,这是代码:

单例.hpp:

#ifndef SINGLETON_HPP
#define SINGLETON_HPP

#include <iostream>

template<int X=100>
class Singleton {
protected:
static Singleton<X> *instance;
public:

static Singleton<X>& getInstance() {
if(!Singleton<X>::instance) {
Singleton<X>::instance = new Singleton<X>();
}
return *Singleton<X>::instance;
}

void foo() {
std::cout << "Test<" << X << ")::foo()" << std::endl;
}
};

#endif

单例.cpp:

#include "Singleton.hpp"

template<int X>
Singleton<X>* Singleton<X>::instance = NULL;

#ifdef SPECIALIZE
template<>
Singleton<100>* Singleton<100>::instance = NULL;
#endif

主要.cpp:

#include "Singleton.hpp"

int main(int ac, char *av[]) {
Singleton<100> &sing = Singleton<100>::getInstance();
sing.foo();
}

然后是三种不同的编译方式,以及输出:

没有专门化,SingletonMain.o 首先链接:

C:\Test>g++ -c Singleton.cpp

C:\Test>g++ -c SingletonMain.cpp

C:\Test>g++ -o Singleton.exe SingletonMain.o Singleton.o
SingletonMain.o:SingletonMain.cpp:(.text$_ZN9SingletonILi100EE11getInstanceEv[Singleton<100>::getInstance()]+0x7): undefined reference to `Singleton<100>::instance'
SingletonMain.o:SingletonMain.cpp:(.text$_ZN9SingletonILi100EE11getInstanceEv[Singleton<100>::getInstance()]+0x1c): undefined reference to `Singleton<100>::instance'
SingletonMain.o:SingletonMain.cpp:(.text$_ZN9SingletonILi100EE11getInstanceEv[Singleton<100>::getInstance()]+0x21): undefined reference to `Singleton<100>::instance'
collect2: ld returned 1 exit status

没有特化,Singleton.o 先链接:

C:\Test>g++ -c Singleton.cpp

C:\Test>g++ -c SingletonMain.cpp

C:\Test>g++ -o Singleton.exe Singleton.o SingletonMain.o
SingletonMain.o:SingletonMain.cpp:(.text$_ZN9SingletonILi100EE11getInstanceEv[Singleton<100>::getInstance()]+0x7): undefined reference to `Singleton<100>::instance'
SingletonMain.o:SingletonMain.cpp:(.text$_ZN9SingletonILi100EE11getInstanceEv[Singleton<100>::getInstance()]+0x1c): undefined reference to `Singleton<100>::instance'
SingletonMain.o:SingletonMain.cpp:(.text$_ZN9SingletonILi100EE11getInstanceEv[Singleton<100>::getInstance()]+0x21): undefined reference to `Singleton<100>::instance'
collect2: ld returned 1 exit status

特化:

C:\Test>g++ -DSPECIALIZE -c Singleton.cpp

C:\Test>g++ -DSPECIALIZE -c SingletonMain.cpp

C:\Test>g++ -DSPECIALIZE -o Singleton.exe Singleton.o SingletonMain.o

现在,这里似乎有人遇到了类似的问题 -- C++ template static member instantiation -- 但“解决方案”是对您可能使用的每种类型进行明确的专门化……这似乎完全违背了模板的目的……所以必须有更好的方法,对吧?

最佳答案

您必须将静态成员定义移动到标题中。就像其他所有模板化的一样,类模板的静态成员的定义必须出现在每个使用它的翻译单元中。这基本上意味着它属于标题。

引用 C++11,[temp]§6:

A function template, member function of a class template, or static data member of a class template shall be defined in every translation unit in which it is implicitly instantiated (14.7.1) unless the corresponding specialization is explicitly instantiated (14.7.2) in some translation unit; no diagnostic is required.

(强调我的)

关于c++ - 除非明确专门化,否则模板类的静态成员不会实例化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19347671/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com