被一个
similar question
我试着以标准中提到的问题为例:
template <typename T, typename U = int> struct S;
template <typename T = int, typename U> struct S
{ void f() { std::cout << __PRETTY_FUNCTION__ << '\n'; } };
int main()
{
S s; s.f();
return 0;
}
上面的代码打印出来
void S<int, int>::f() [T = int, U = int]
compiled with gcc HEAD 8.0.1 201803
但无法使用编译
clang HEAD 7.0.0
除非在实例化过程中使用尖括号:
S s; s.f(); // error: declaration of variable 's' with deduced type 'S' requires an initializer
S<> t; t.f(); // Correct
撇开这个问题不谈,我已经检查了另一个
模板风格
对于这种特殊行为,代码以非常不规则的方式被接受或拒绝:
Template function
template <typename T, typename U = int> void function();
template <typename T = int, typename U> void function()
{ std::cout << __PRETTY_FUNCTION__ << '\n'; }
int main()
{
/* Rejected by GCC: no matching function for call to 'function()'
template argument deduction/substitution failed:
couldn't deduce template parameter 'T'
same error with function<>()
CLang compiles without issues */
function(); // CLang prints 'void function() [T = int, U = int]'
return 0;
}
Template variable
template <typename T, typename U = int> int variable;
template <typename T = int, typename U> int variable = 0;
int main()
{
/* GCC complains about wrong number of template arguments (0, should be at least 1)
while CLang complains about redefinition of 'variable' */
std::cout << variable<> << '\n';
return 0;
}
Template alias
template <typename T, typename U = int> using alias = int;
template <typename T = int, typename U> using alias = int;
int main()
{
/* GCC complains about redefinition of 'alias'
while CLang compiles just fine. */
alias<> v = 0;
std::cout << v << '\n';
return 0;
}
这个
standards text
关于这个特性,没有区分不同的模板类型,所以我认为它们的行为应该相同。
但是,两个编译器都拒绝使用模板变量,因此我对模板变量选项有一些疑问。对我来说,CLang拒绝模板变量抱怨重新定义是正确的,而GCC拒绝
错误的原因
,但这一推理并没有遵循[温度参数]/10中的标准。
那么对于模板变量,我应该期望什么呢
-
由于重新定义,代码被拒绝(CLang是正确的)。
-
接受代码,合并两个模板定义(GCC和CLang都是错误的)。