16

我之前有一个问答: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

 

有两种可能:

一世。如果声明点在 after =,则在语句末尾:

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

4 回答 4

19
auto x = x; // inner x

格式不正确。

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

7.1.6.4 自动说明符

...

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

因此,因为x=解决了xin之后auto x(如您链接的问题中所解释的那样),上面的代码格式不正确。

于 2013-10-02T09:22:39.730 回答
10

就像在任何其他类型的定义中一样,x初始化器右侧的 forauto x = x解析为 local auto x。C++ 一直这样做(即int x = x编译但会给你未定义的行为)。

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

就像任何其他类型的声明一样,x在其声明符 is 之后的范围内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.
}
于 2013-10-02T09:15:17.320 回答
5

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

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

结果(gcc):

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

或(叮当声):

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

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

于 2013-10-02T09:23:37.093 回答
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,你正在重新定义相同的变量名。那是无效的!auto y = x应该工作。

于 2013-10-02T09:15:35.320 回答