在自己的默认值中使用参数名称 - 是否合法?

时间:2016-11-09 17:53:57

标签: c++ parameters language-lawyer default-parameters

enum class E {
    One,
    Two
};

void foo(E value = decltype(value)::One) {
}

可以使用Clang(3.9)编译,但不能使用GCC 6.1编译:{{1​​}}。

什么编译器是对的?

1 个答案:

答案 0 :(得分:8)

根据[basic.scope.pdecl]/1

  

名称的声明点在完成后立即生效   声明者(第8条)和初始值设定项 之前(如果有的话),除了   如下所述。

因此该参数在该点明确声明。如何在decltype中使用它?措辞已经过时,无意中不允许这样做。见core issue 2082

  

根据8.3.6 [dcl.fct.default]第9段,

     
    

每次调用函数时都会计算默认参数     没有相应参数的参数。评估顺序     函数参数未指定。因此,参数a     函数不应在默认参数中使用,即使它们不是     评估。这禁止在未评估的操作数中使用参数,     如,

  
void foo(int a = decltype(a){});
     

这个措辞早于这个概念   “未评估的操作数”(短语“未评估”是指电话   到提供实际参数的函数,从而得到   不使用默认参数,不使用未评估的操作数)   不适用于此类案件。

所以quoted paragraph被修改为阅读

  

参数不应作为默认参数中潜在评估的表达式出现。

由于decltype的操作数未经评估,现在这很好,GCC错了。