C ++ lambda默认参数编译器是否行为不当? [英] C++ lambda default arguments compiler misbehavior?
问题描述
以下哪些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屋!