c++ - sizeof 是否可以在 lambda 中应用于未捕获的变量,或者这是一个编译器错误?

标签 c++ c++11

这是讨论的跟进 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 the lambda-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/

相关文章:

c++ - Visual Studio 2017,C++,单步执行代码时指向错误的行

c++ - HDF5 - 通过代码为组创建属性

c++ - 关于 boost::recursive_mutex,boost::thread_group 中的所有线程是否共享同一个线程

c++ - 如何仅测试字母的 u32string(使用语言环境)

c++ - 交换类型列表中的两种类型

c++ - 使用算法查找自定义数据 vector 中的最大值和最小值

c++ - boost 元组是可变的吗?

c++ - 采用 std::vector 或 std::array 的模板函数

c++ - jsoncpp operator= 中的 undefined reference

c++ - 如果没有 "usleep()"或 "printf",While 循环将不会终止