![](/img/trans.png)
[英]Why is it possible to pass a void(*)(int x, int y) to attachInterrupt that expects void(*)()?
[英]Why is int x{ y = 5 } possible?
int main() {
int y;
int x{ y = 5 };
//x is 5
}
这怎么可能,因为 y = 5 不是可计算的表达式?
另外,为什么编译器或 IDE 不抱怨 main() 没有返回 int?
这怎么可能,因为 y = 5 不是可计算的表达式?
它是一个赋值,赋值产生值,即“左操作数的 cv 非限定类型”,参见[expr.ass/3] 。 因此y = 5
导致y
,即5
,用于初始化x
。
关于您的第二个问题,请参阅 cppreference on main (或[basic.start.main/5] ):
main function 的主体不需要包含
return
语句:如果控制到达 main 的末尾而没有遇到return
语句,则效果为执行return 0;
.
因此,编译器或 IDE 在main
末尾警告您缺少return
语句是完全错误的。 诚然,您应该始终从非void
函数( execpt main
) return
对象的事实有点……好吧,我猜是出于历史原因。
operator=()
产生一个值,该值是分配给变量的值。 因此,可以像这样链接分配:
int x, y, z;
x = y = z = 1;
我将从你的最后一个问题开始
另外,为什么编译器或 IDE 不抱怨 main() 没有返回 int?
根据C++标准(6.6.1主要功能)
5 main 中的 return 语句具有离开 main function(销毁具有自动存储持续时间的任何对象)并以返回值作为参数调用 std::exit 的效果。 如果控制从 main 的复合语句的末尾流出,则效果等同于操作数为 0 的返回(另见 18.3)。
相对于这个问题
这怎么可能,因为 y = 5 不是可计算的表达式?
来自 C++ 标准(8.18 赋值和复合赋值运算符)
1 赋值运算符 (=) 和复合赋值运算符都从右到左分组。 所有这些都需要一个可修改的左值作为它们的左操作数,并返回一个指向左操作数的左值。
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';
}
它的 output 是
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;
}
程序 output 是
x1 = 5
*x2.begin()= 10
y = 10
如果您查看 有关 cppreference 的文档,您会看到operator=()
返回对已分配的 object 的引用。 因此,赋值可以用作返回被赋值的 object 的表达式。
然后,这只是一个带大括号的正常赋值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.