今天,我和我的一个 friend 在一个愚蠢的错误上挣扎了很多,我让我想知道模板参数在 C++ 中是如何工作的。考虑以下代码,我尝试部分特化一个类 attr<MyClass<I>>
,其中 I
是一个 unsigned int
,尽管 MyClass
需要一个 int
参数:
#include <iostream>
template<int I>
class MyClass
{
};
template<typename T>
struct attr;
template<unsigned int I>
struct attr<MyClass<I>>
{
};
int main(int argc, char *argv[])
{
attr<MyClass<1>> att;
return 0;
}
g++
失败并显示错误消息main.cpp: In function ‘int main(int, char**)’:
main.cpp:20:22: erreur : aggregate ‘attr<MyClass<1> > att’ has incomplete type and cannot be defined
attr<MyClass<1>> att;
并且
clang
编译它(由于 att
未使用,因此只是一个警告)。所以我想知道:
clang
模板参数的类型比 g++
的弱吗? 最佳答案
是的,至少根据现行标准,GCC 拒绝是正确的。也许 Clang 人在这里实现了一些缺陷报告,我不知道。
http://eel.is/c++draft/temp.deduct.type#17
他们在测试套件中的测试用例仅针对函数进行测试,对于这些函数,它们似乎会发出合理的错误消息: https://github.com/llvm-mirror/clang/blob/master/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p17.cpp 。
此外,由于永远无法推导出部分特化,我们还会遇到 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#549 ,它询问是否应该预先拒绝此类构造。在我看来,如果您愿意,可以应用 http://eel.is/c++draft/temp.res#8:
没有合法的方法来触发该模板的实例化,因此您可能会争辩说无法为其生成有效的特化。在这种解释下,行为是未定义的,任何事情都是合法的。
关于C++ 模板参数和偏特化 : strong or weak typing?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60704051/