c++ - 无法在未定义的情况下声明模板变量

标签 c++ templates c++14 variable-templates

我想在头文件中转发声明变量模板,然后在单独的编译单元中进行实际实例化。

我被引导相信 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/

相关文章:

c++ - C++ 中的编译时条件成员函数调用

c++ - 返回析构函数有副作用的对象

c++ - 我怎样才能正确解析我的文件? (使用中断/继续)

c++ - 我应该如何编写我的 C++ 来为 C++ 模块做好准备?

c++ - 关闭 HANDLES 和其他 WINAPI 的模板类?

excel - Kendo Grid Excel 导出,带有下拉模板的列

c++ - 泛型在 C++/CX 中的工作原理

c++ - 递归类型真的是构建非连续任意大小数据结构的唯一方法吗?

c++ - 懒惰评估(短路)模板条件类型的通用方法

c++ - 通过参数或返回值修改