这是讨论的跟进 found here .
以下代码在 gcc 和 clang ( live demo ) 下编译。对于行 //1
中的情况,这是令人惊讶的,因为 lambda 不捕获任何内容。对于 MCR2
的情况,其中 lambda 返回指针本身,我们得到预期的编译时错误(行 //Will not compile
)。运算符 sizeof
的应用与返回指针有何不同?
#include <iostream>
#define MCR1(s) \
([]() { return sizeof(s); })()
#define MCR2(s) \
([]() { return s; })()
int main() {
auto *s= "hello world";
auto x1 = MCR1( s ); //1
auto y1 = MCR1( "hello world" );
// auto x2= MCR2( s ); // Will not compile
auto y2= MCR2( "hello world" );
std::cout << x1 << " " << y1 << '\n';
std::cout // << x2 << " "
<< y2 << '\n';
}
编辑: 跟进这里的讨论是另一个例子。令人惊讶的是,标记为 //2
的行现在可以在 gcc7(开发版)下编译 ( live demo )。此处的区别在于表达式现在标记为 constexpr
。
#include <iostream>
#define MCR1(s) \
([]() { return sizeof(s); })()
#define MCR2(s) \
([]() { return s; })()
int main() {
auto constexpr *s= "hello world";
auto constexpr x1= MCR1( s );
auto constexpr y1= MCR1( "hello world" );
auto constexpr x2= MCR2( s ); //2
auto constexpr y2= MCR2( "hello world" );
std::cout << x1 << " " << y1 << '\n';
std::cout << x2 << " " << y2 << '\n';
}
最佳答案
不同之处在于(缺乏)上下文评估。 sizeof
未计算。
根据 N3337(≈C++11)
§5.1 2 [expr.prim.lambda] / 11
If a lambda-expression has an associated capture-default and its compound-statement odr-uses
this
or a variable with automatic storage duration and the odr-used entity is not explicitly captured, then the odr-used entity is said to be implicitly captured;
和
§5.1.2 [expr.prim.lambda] / 12
If a lambda-expression odr-uses
this
or a variable with automatic storage duration from its reaching scope, that entity shall be captured by thelambda-expression
. If a lambda-expression captures an entity and that entity is not defined or captured in the immediately enclosing lambda expression or function, the program is ill-formed.
ODR 使用意味着在潜在评估的上下文中使用:
§3.2 [basic.def.odr] / 2
An expression is potentially evaluated unless it is an unevaluated operand or a subexpression thereof. A variable whose name appears as a potentially-evaluated expression is odr-used unless it is an object that satisfies the requirements for appearing in a constant expression and the lvalue-to-rvalue conversion is immediately applied
因为 sizeof
不是,并且 s
在 lambda 表达式的 reaching scope 中,所以没关系。不过,返回 s
意味着对其求值,这就是它格式错误的原因。
关于c++ - sizeof 是否可以在 lambda 中应用于未捕获的变量,或者这是一个编译器错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40406560/