C++ 模板参数和偏特化:强类型还是弱类型?
C++ template parameter and partial specialization : strong or weak typing?
今天,我和我的一个朋友在一个愚蠢的错误上苦苦挣扎,我想知道模板参数在 C++ 中是如何工作的。考虑以下代码,我尝试部分特化 class 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
If P has a form that contains <i>
, and if the type of the corresponding value of A differs from the type of i, deduction fails. If P has a form that contains [i]
, and if the type of i is not an integral type, deduction fails.
他们的测试套件中的测试用例仅针对函数进行测试,它们似乎会发出合理的错误消息: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 , which asks whether such constructs should possibly be rejected up-front. In my opinion, http://eel.is/c++draft/temp.res#8 中:
"Knowing which names are type names allows the syntax of every template to be checked. The program is ill-formed, no diagnostic required, if:
- no valid specialization can be generated for a template and that template is not instantiated, or ..."
没有合法的方式来触发该模板的实例化,因此您可以争辩说不能为它生成有效的专业化。根据这种解释,行为是不确定的,任何事情都是合法的。
今天,我和我的一个朋友在一个愚蠢的错误上苦苦挣扎,我想知道模板参数在 C++ 中是如何工作的。考虑以下代码,我尝试部分特化 class 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
If P has a form that contains
<i>
, and if the type of the corresponding value of A differs from the type of i, deduction fails. If P has a form that contains[i]
, and if the type of i is not an integral type, deduction fails.
他们的测试套件中的测试用例仅针对函数进行测试,它们似乎会发出合理的错误消息: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 , which asks whether such constructs should possibly be rejected up-front. In my opinion, http://eel.is/c++draft/temp.res#8 中:
"Knowing which names are type names allows the syntax of every template to be checked. The program is ill-formed, no diagnostic required, if:
- no valid specialization can be generated for a template and that template is not instantiated, or ..."
没有合法的方式来触发该模板的实例化,因此您可以争辩说不能为它生成有效的专业化。根据这种解释,行为是不确定的,任何事情都是合法的。