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

时间:2013-05-28 17:22:09

标签: c++ templates visual-studio-2012 c++11

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

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

在Visual Studio 2012中。

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

我错过了什么吗?

3 个答案:

答案 0 :(得分:7)

您的计划格式正确。 C ++ 11标准的第14.7.2 / 11段规定:

  

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

您的程序遵守此约束,不会破坏任何其他规则。因此,这符合VC11中的错误。

答案 1 :(得分:3)

似乎已向Microsoft Connect 620017报告了此问题:

  

Microsoft于12/3/2010发表于1:52 PM

     
    

您好,

         

正如您所指出的,我们的extern模板实现没有     符合C ++ - 0x标准。我们还有旧的扩展名     实现。虽然我们没有资源来实现     C ++ - 下一版Visual Studio的此功能的0x版本,     一致性问题是我们的优先事项;我们目前打算这样做     在Visual Studio的未来版本中实现此功能。

         

感谢您抽出宝贵时间报告此问题。我们非常感激。

         

Jamie Eckman Visual C ++团队

  

那是从2010年开始的,所以“下一次发布”他的意思是VS2012。

答案 2 :(得分:3)

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