我有以下代码,它使用gcc 4.4编译,没有警告,并返回42。
template<typename T>
struct foo
{ };
template<typename T>
struct foo<void (T)>
{
enum { value = 42 };
};
int main()
{
return foo<void ((int))>::value;
}
现在,我知道为什么它在模板参数为void (int)
时应该有效,但双括号的处理是什么?这在C ++中是否合法?它与void (int)
相同吗?
干杯
答案 0 :(得分:4)
在这种情况下,void ((int))
与void (int)
相同
void ((int))
中的foo<void ((int))>
部分称为type-id
根据§8.1/ 1,type-id
由...组成
type-specifier-seq
和abstract-declarator
。
在void ((int))
,type-specifier-seq
为void
和abstract-declarator
是((int))
,
abstract-declarator
可以任意加括号
这在C和C ++中是合法的。
答案 1 :(得分:3)
内括号用于更改表达式的求值顺序。
表示,当表达式只有一个部分时,顺序无关紧要。答案 2 :(得分:1)
模板与宏不同。
您的“void(T)”与“void T”相同,“void((int))”与“void int”相同,就像“void((((int)))”与“void int”相同。 括号中的表达式被评估为@Mark指出。
答案 3 :(得分:0)
在这种情况下,为了这个目的,不是必需的,但这样的双重parens的主要原因是避免最令人烦恼的解析。
函数声明中不允许双重parens,但是在函数调用中,因此通过在双括号中包含至少一个参数,可以强制将产生最令人烦恼的解析的代码作为函数调用。
我在previous answer中包含的一些代码证明了这一点。