以下代码声明了一个模板,声明了一个显式的实例化定义,然后声明了一个显式的实例化声明:
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的印象,这应该是有效的,因为定义遵循声明。
我错过了什么吗?
答案 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,因为看起来您现在正在尝试抑制已经显式实例化的内容。