Tom*_*rly 5 c++ templates variable-templates c++14
我想在头文件中转发声明变量模板,然后在单独的编译单元中进行实际实例化.
我被引导相信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;
Run Code Online (Sandbox Code Playgroud)
上面的代码示例在GCC下编译并按原样运行.但是,取消注释第10行会产生编译时错误:
specialization of 'variable<char>' after instantiation
template <> int variable<char> = 23;
^
Run Code Online (Sandbox Code Playgroud)
我认为你走在正确的道路上。
诀窍是:在任何一个翻译单元中,不要在专业化之前实例化模板。
例如:
// 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
Run Code Online (Sandbox Code Playgroud)
然后:
// test2.cpp
#include "test.h"
template <> int variable<char> = 23;
template <> int variable<int> = 24;
Run Code Online (Sandbox Code Playgroud)
最后:
// test.cpp
#include "test.h"
#include <iostream>
int
main()
{
std::cout << variable<char> << '\n';
std::cout << variable<int> << '\n';
}
Run Code Online (Sandbox Code Playgroud)
对我来说这个输出:
23
24
Run Code Online (Sandbox Code Playgroud)
更新
TC 在下面的评论中指出,在首次使用之前需要声明专业化,因此我更新了上面的“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;
Run Code Online (Sandbox Code Playgroud)
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>;
^~~~~~
Run Code Online (Sandbox Code Playgroud)
我搜索了标准和核心问题列表,但找不到任何表明一个编译器或另一个编译器正确的信息。如果有人确实看到了这样的证据,我很乐意将其包含在这个答案中。