auto关键字的声明点

时间:2013-10-02 09:05:38

标签: c++ c++11

之前我有一个Q& A:Point of declaration in C++。规则声明点很好地适用于许多情况。现在,我混淆了auto与此规则相结合的用法。

考虑这两个代码:

我。单独声明x (我们不希望它起作用)

{
  auto x = x;
}

II。通过外部x 声明内部x(它在gcc 4.8.x中出错)

{
  int x = 101; // the outer x
  {
    auto x = x; // the inner x
  }
}

根据宣言点的规则,它应该有效,但事实并非如此。似乎标准中有另一条规则我错过了它。问题是, 使用auto时的声明点在哪里?

有两种可能性:

我。如果声明点在=之后,则在声明的末尾:

auto object = expression;
                        ^
                        Is it here? If it is, why gcc complains?

所以第二个声明是有效的并且必须有效,因为没有x但是那个外部声明(之前声明)。因此,auto x=x有效且内部x应分配给101

II。如果声明点在=之前:

auto object = expression;
           ^

嗯,这没有任何意义,因为auto必须等到看到以下表达式。例如auto x;无效。


更新:我需要一个答案,通过规则声明解释它。

4 个答案:

答案 0 :(得分:19)

auto x = x; // inner x

是不正确的。

引用C ++ 11标准(强调我的):

  

7.1.6.4自动说明符

     

...

     

3 否则,变量的类型是从其初始化程序推导出来的。 声明的变量的名称   不应出现在初始化表达式中。 ...

因为x之后=解析为x中的auto x(如您所链接的问题中所述),上面的代码就是格式错误

答案 1 :(得分:10)

与任何其他类型的定义一样,x的初始化设备右侧的auto x = x会解析为本地auto x。 C ++总是这样做(即int x = x编译但会给你未定义的行为。)

auto x = x无法编译的原因是因为虽然x在范围内,但它还没有已知的类型,因此使用它作为初始化失败,因为无法从表达式推断出类型

就像任何其他类型的声明一样,x在其声明者auto x之后的范围内。

int x = 10;
int y = 20;
{
    int x = x;  // This is NOT the outer x. This is undefined behaviour (reading an
                // uninitialised variable).
    auto y = y; // This is NOT the outer y. This is a compile error because the type of
                // y is not known.
}

答案 2 :(得分:4)

只需添加一个更明确的诊断示例:

auto ll = [&] { ll(); };

结果(gcc):

error: variable ‘auto ll’ with ‘auto’ type used in its own initializer

或(clang):

error: variable 'll' declared with 'auto' type cannot appear in its own initializer
    auto ll = [&] { ll(); };
                    ^

您可以看到有明确的规则。我没看过规格。

答案 3 :(得分:1)

编译器读取整个语句(从行的开头到下一个分号),然后使用操作优先级评估语句的不同部分,然后在{{1将被分配,即auto x符号后出现的类型。

例如:

=

关于您的template <typename T> T sum(T a, T b) { return a+b; } int main() { auto x = sum<double>(1,5); // x here is a double, because the return value is double auto y = sum<int>(1,7); //y is an int, because the return value is int } ,您正在重新定义相同的变量名称。那是无效的! auto x = x应该有用。