C ++ lambda默认参数编译器是否行为不当? [英] C++ lambda default arguments compiler misbehavior?

查看:115
本文介绍了C ++ lambda默认参数编译器是否行为不当?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下哪些C ++ lambda/语句应根据最新的C ++规范运行?

Which of the following C++ lambdas/statements are supposed to work according to the latest C++ specification?

相关的上下文:请参见此处.

我在带有clang 11.0.0和gcc 10.2.1的Fedora 33上使用-std=c++17测试了以下代码段.

I tested the following code snippets with -std=c++17 on Fedora 33 with clang 11.0.0 and gcc 10.2.1.

更新:将__PRETTY_FUNCTION__替换为__func__以符合标准.可以观察到相同的行为.

Update: Replace __PRETTY_FUNCTION__ with __func__ for standard compliance. The same behavior can be observed.

Update2 :示例使用const char * s = __func__作为默认参数来验证它在函数范围内是否有效(由于@BenVoigt).

Update2: Example using const char * s = __func__ as default argument to verify that it should be valid within a function scope (thanks to @BenVoigt).

void clang() {
  [](const char* c = __func__) {std::cout << c << std::endl;}();
}

预期的行为(CLANG):

  • 打印出clang\n(对于__PRETTY_FUNCTION__,为void clang())
  • Print out clang\n (void clang() for __PRETTY_FUNCTION__)

观察到的行为(CLANG):

  • 编译器警告:warning: predefined identifier is only valid inside function [-Wpredefined-identifier-outside-function]
  • 打印出\n(对于__PRETTY_FUNCTION__,为top level())
  • Compiler warning: warning: predefined identifier is only valid inside function [-Wpredefined-identifier-outside-function]
  • Print out \n (top level() for __PRETTY_FUNCTION__)
template <typename L>
constexpr std::string_view methodName(L l) { return l(); }
#define __METHOD_NAME__ (\
  __func__, /* needed for pointer to work */ \
  methodName([](const char* c = __func__) {return std::string_view(c);}) \
)
void gcc1() {
  std::cout << [](const char* c = __func__) { return c; }() << std::endl;  // GCC: This statement doesn't do anything
  std::cout << [](const char* c = __func__) { return c; }("gcc") << std::endl;
  std::cout << __METHOD_NAME__ << std::endl;  // GCC: This statement somehow conflicts with the statements above
}
void gcc2() {
  std::cout << __METHOD_NAME__ << std::endl;  // GCC: This statement itself works
}

预期输出(GCC):

gcc1
gcc
gcc1
gcc2

实测输出(GCC):

gcc
gcc2


3. GCC编译错误

void gcc3() {
  std::string_view s = [](const char* c = __func__) { return std::string_view(c); }();
  std::cout << s << std::endl;
}

预期行为(GCC):编译没有问题.

观察到的行为(GCC): error: internal compiler error: in finish_expr_stmt

推荐答案

[class.local]本地类在封闭范围内,并且对函数外部的名称具有与封闭函数相同的访问权限. [注:本地类中的声明不能从封闭范围内使用(6.2)本地实体. —尾注]

[class.local] The local class is in the scope of the enclosing scope, and has the same access to names outside the function as does the enclosing function. [Note: A declaration in a local class cannot odr-use (6.2) a local entity from an enclosing scope. — end note]

lambda是一个本地类,因此它不能使用封闭范围(例如__func__)中的变量(除了在其捕获子句中).

A lambda is a local class, and as such it cannot use variables from the enclosing scope (e.g. __func__) other than in its capture clause.

这篇关于C ++ lambda默认参数编译器是否行为不当?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆