VS 2012中的显式模板声明/定义

Explicit template declaration/definition in VS 2012

本文关键字:声明 定义 2012 VS      更新时间:2023-10-16

下面的代码声明一个模板,声明一个显式实例化定义,然后声明一个显式实例化声明:

template <typename T>
T Double(T number)
{
    return number * 2;
}
extern template int Double<int>(int);  // declaration
template int Double<int>(int t);       // definition
int main(int argc, char* argv[])
{
    int n = Double(10);
    return 0;
}

给出错误:

error C2929: 'int Double<int>(int)' : explicit instantiation; cannot explicitly force and suppress instantiation of template-class member

我从http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1987.htm得到的印象是,这应该是有效的,因为定义遵循声明。

我错过了什么吗?

程序格式良好。c++ 11标准第14.7.2/11段规定:

如果一个实体是显式实例化声明和显式实例化定义的主题在同一翻译单元中,定义应遵循声明。[…]

你的程序尊重这个约束并且不违反任何其他规则。因此,这是VC11中的一个bug。

这个问题似乎已经报告给Microsoft Connect 620017:

Microsoft于12/3/2010 at 1:52 PM发布

你好,

正如您所注意到的,我们的外部模板的实现没有符合c++ -0x标准。我们还用原来的分机号实现。虽然我们没有资源来实现下一个Visual Studio版本的c++ -0x版本,一致性问题是我们的首要任务;我们目前确实打算这么做在Visual Studio的未来版本中实现此功能。

感谢您花时间报告这个问题。非常感谢。

Jamie Eckman Visual c++ Team

那是2010年的,所以他说的"下一个版本"指的是VS2012。

这个Visual c++一致性错误在Visual Studio 2013中得到了解决,可以在这里找到。这个修复使得可以将extern template声明放在头文件中以抑制模板实例化,并且仍然可以在一个模块中声明显式实例化,这可以减少编译时间和代码膨胀。反转语句(即,显式实例化请求,后跟具有相同模板参数的extern template声明)仍然会导致错误C2929,因为看起来您现在正在试图抑制已经显式实例化的东西。