我想在头文件中转发声明变量模板,然后在单独的编译单元中进行实际实例化。
我被引导相信 C++14 变量模板的操作与静态类变量非常相似。不幸的是,情况似乎并非如此,它阻止我向前声明我的变量模板。
template <typename T> struct Variable {
static int variable;
};
template <typename T>
extern int variable;
int main() {
(void) Variable<char>::variable;
// (void) variable<char>; // <-- line 10
}
template <> int Variable<char>::variable = 42;
template <> int variable<char> = 23;
上面的代码示例在 GCC 下按原样编译和运行。但是取消注释第 10 行会产生编译时错误:
specialization of 'variable<char>' after instantiation
template <> int variable<char> = 23;
^
最佳答案
我认为您的方向是正确的。
技巧是这样的:在任何一个翻译单元中,不要在您的特化之前实例化模板。
例如:
// test.h
#ifndef TEST_H
#define TEST_H
template <typename T>
extern int variable;
template <> extern int variable<char>;
template <> extern int variable<int>;
#endif // TEST_H
然后:
// test2.cpp
#include "test.h"
template <> int variable<char> = 23;
template <> int variable<int> = 24;
最后:
// test.cpp
#include "test.h"
#include <iostream>
int
main()
{
std::cout << variable<char> << '\n';
std::cout << variable<int> << '\n';
}
对我来说这个输出:
23
24
更新
T.C.在下面的评论中指出,需要在首次使用之前声明特化,因此我更新了上面的“test.h”来做到这一点。
更新 2
似乎存在一些实现分歧。 clang 似乎可以很好地处理这个问题:
template <typename T>
extern int variable;
template <> extern int variable<char>;
template <> extern int variable<int>;
#include <iostream>
int
main()
{
std::cout << variable<char> << '\n';
std::cout << variable<int> << '\n';
}
template <> int variable<char> = 23;
template <> int variable<int> = 24;
http://melpon.org/wandbox/permlink/DGYKvvoPbmRIHaFi
但是 gcc 报错:
prog.cc:4:13: error: explicit template specialization cannot have a storage class
template <> extern int variable<char>;
^~~~~~
prog.cc:5:13: error: explicit template specialization cannot have a storage class
template <> extern int variable<int>;
^~~~~~
我已经搜索了标准和核心问题列表,但找不到任何表明一个编译器或另一个编译器正确的信息。如果有人确实看到了这样的证据,我很乐意将其包含在这个答案中。
关于c++ - 无法在未定义的情况下声明模板变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34970693/