为什么 int x{ y = 5 } 可能?
Why is int x{ y = 5 } possible?
int main() {
int y;
int x{ y = 5 };
//x is 5
}
这怎么可能,因为 y = 5 不是可计算的表达式?
此外,为什么编译器或 IDE 不抱怨 main() 没有返回 int?
How is this possible, since y = 5 is not a calculable expression?
这是一个赋值,赋值产生值,即"cv-unqualified type of the left operand",见[expr.ass/3]。因此 y = 5
导致 y
,即 5
,用于初始化 x
。
关于您的第二个问题,请参阅 main (or [basic.start.main/5] 上的 cppreference):
The body of the main function does not need to contain the return
statement: if control reaches the end of main without encountering a return
statement, the effect is that of executing return 0;
.
因此,编译器或 IDE 警告您 main
末尾缺少 return
语句将是完全错误的。不可否认,你应该总是 return
来自非 void
函数的对象 execpt main
有点......好吧,出于历史原因我猜。
如果您查看 the documentation on cppreference,您会看到 operator=()
return 是对已分配对象的引用。因此,赋值可以用作 return 被赋值对象的表达式。
那么,这只是一个带大括号的普通赋值。
operator=()
产生一个值,这是分配给变量的值。因此,可以像这样链接赋值:
int x, y, z;
x = y = z = 1;
我将从你最后一个问题开始
Also, why doesn't the compiler or IDE complain about main() not
returning an int?
根据 C++ 标准(6.6.1 主函数)
5 A return statement in main has the effect of leaving the main
function (destroying any objects with automatic storage duration) and
calling std::exit with the return value as the argument. If control
flows off the end of the compound-statement of main, the effect is
equivalent to a return with operand 0 (see also 18.3).
相对于这个问题
How is this possible, since y = 5 is not a calculable expression?
来自 C++ 标准(8.18 赋值和复合赋值运算符)
1 The assignment operator (=) and the compound assignment operators
all group right-to-left. All require a modifiable lvalue as their left
operand and return an lvalue referring to the left operand.
Sp 这个声明
int x{ y = 5 };
可以等价地拆分成两条语句
y = 5;
int x{ y };
此外,在 C++ 中,您甚至可以通过以下方式引用变量 y
int &x{ y = 5 };
这是一个演示程序
#include <iostream>
int main()
{
int y;
int &x{ y = 5 };
std::cout << "y = " << y << '\n';
x = 10;
std::cout << "y = " << y << '\n';
}
它的输出是
y = 5
y = 10
你可以这样声明
int x{ y = 5 };
重写也喜欢
int x = { y = 5 };
但是请注意,这两个声明之间存在差异(看起来与上述声明类似)。
auto x{ y = 5 };
和
auto x = { y = 5 };
在第一个声明中,变量 x
的类型为 int
。
在第二个声明中,变量 x
的类型为 std::initializer_list<int>
.
要使差异更明显,请查看对象的值是如何输出的。
#include <iostream>
int main()
{
int y;
auto x1 { y = 5 };
std::cout << "x1 = " << x1 << '\n';
auto x2 = { y = 10 };
std::cout << "*x2.begin()= " << *x2.begin() << '\n';
std::cout << "y = " << y << '\n';
return 0;
}
程序输出为
x1 = 5
*x2.begin()= 10
y = 10
int main() {
int y;
int x{ y = 5 };
//x is 5
}
这怎么可能,因为 y = 5 不是可计算的表达式?
此外,为什么编译器或 IDE 不抱怨 main() 没有返回 int?
How is this possible, since y = 5 is not a calculable expression?
这是一个赋值,赋值产生值,即"cv-unqualified type of the left operand",见[expr.ass/3]。因此 y = 5
导致 y
,即 5
,用于初始化 x
。
关于您的第二个问题,请参阅 main (or [basic.start.main/5] 上的 cppreference):
The body of the main function does not need to contain the
return
statement: if control reaches the end of main without encountering areturn
statement, the effect is that of executingreturn 0;
.
因此,编译器或 IDE 警告您 main
末尾缺少 return
语句将是完全错误的。不可否认,你应该总是 return
来自非 void
函数的对象 execpt main
有点......好吧,出于历史原因我猜。
如果您查看 the documentation on cppreference,您会看到 operator=()
return 是对已分配对象的引用。因此,赋值可以用作 return 被赋值对象的表达式。
那么,这只是一个带大括号的普通赋值。
operator=()
产生一个值,这是分配给变量的值。因此,可以像这样链接赋值:
int x, y, z;
x = y = z = 1;
我将从你最后一个问题开始
Also, why doesn't the compiler or IDE complain about main() not returning an int?
根据 C++ 标准(6.6.1 主函数)
5 A return statement in main has the effect of leaving the main function (destroying any objects with automatic storage duration) and calling std::exit with the return value as the argument. If control flows off the end of the compound-statement of main, the effect is equivalent to a return with operand 0 (see also 18.3).
相对于这个问题
How is this possible, since y = 5 is not a calculable expression?
来自 C++ 标准(8.18 赋值和复合赋值运算符)
1 The assignment operator (=) and the compound assignment operators all group right-to-left. All require a modifiable lvalue as their left operand and return an lvalue referring to the left operand.
Sp 这个声明
int x{ y = 5 };
可以等价地拆分成两条语句
y = 5;
int x{ y };
此外,在 C++ 中,您甚至可以通过以下方式引用变量 y
int &x{ y = 5 };
这是一个演示程序
#include <iostream>
int main()
{
int y;
int &x{ y = 5 };
std::cout << "y = " << y << '\n';
x = 10;
std::cout << "y = " << y << '\n';
}
它的输出是
y = 5
y = 10
你可以这样声明
int x{ y = 5 };
重写也喜欢
int x = { y = 5 };
但是请注意,这两个声明之间存在差异(看起来与上述声明类似)。
auto x{ y = 5 };
和
auto x = { y = 5 };
在第一个声明中,变量 x
的类型为 int
。
在第二个声明中,变量 x
的类型为 std::initializer_list<int>
.
要使差异更明显,请查看对象的值是如何输出的。
#include <iostream>
int main()
{
int y;
auto x1 { y = 5 };
std::cout << "x1 = " << x1 << '\n';
auto x2 = { y = 10 };
std::cout << "*x2.begin()= " << *x2.begin() << '\n';
std::cout << "y = " << y << '\n';
return 0;
}
程序输出为
x1 = 5
*x2.begin()= 10
y = 10