无法在不定义模板变量的情况下声明模板变量

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)

How*_*ant 3

我认为你走在正确的道路上。

诀窍是:在任何一个翻译单元中,不要在专业化之前实例化模板。

例如:

// 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)

我搜索了标准和核心问题列表,但找不到任何表明一个编译器或另一个编译器正确的信息。如果有人确实看到了这样的证据,我很乐意将其包含在这个答案中。