`auto(expr)` 在表达式语句的开头是否被视为强制转换?
Is `auto(expr)` treated as cast at the beginning of the expression statement?
我有一个简单的代码片段如下所示 (https://godbolt.org/z/cPT3PhYdj):
int main() {
int x = 1;
auto(1); // ok in GCC, error in Clang
auto{1}; // ok in GCC, error in Clang
static_cast<void>(auto(x)); // ok
auto{x}; // ok in GCC, error in Clang
auto(x); // both error in GCC an Clang
}
GCC 和 Clang 都发出错误显示:
// by GCC Trunk [-std=c++23]
<source>: In function 'int main()':
<source>:7:3: error: declaration of 'auto x' has no initializer
7 | auto(x); // why
| ^~~~
Compiler returned: 1
// by Clang Trunk [-std=c++2b]
<source>:3:8: error: expected unqualified-id
auto(1); // why
^
<source>:3:8: error: expected ')'
<source>:3:7: note: to match this '('
auto(1); // why
^
<source>:4:7: error: expected unqualified-id
auto{1}; // why
^
<source>:6:7: error: expected unqualified-id
auto{x}; // why
^
<source>:7:8: error: redefinition of 'x'
auto(x); // why
^
<source>:2:7: note: previous definition is here
int x = 1;
^
<source>:7:8: error: declaration of variable 'x' with deduced type 'auto' requires an initializer
auto(x); // why
^
6 errors generated.
Compiler returned: 1
如果 C++23 是实验性的,他们是否能够修复歧义或更改消歧,因为另一个 auto(expr)
被引入,或者只是保留它?
这些表达式应该被解析为表达式语句中的显式类型衰减转换 auto(expr)
或 auto{expr}
还是被解析为声明?
如果没有歧义,那么哪个优先级在前:
auto(identifier)
为 auto identifier
?, 或
auto(identifier)
as cast expression?
auto ( expression ) (8) (since C++23)
auto { expression } (9) (since C++23)
8,9) The auto
specifier is replaced with the deduced type of the invented variable x
declared with auto x(expression);
(which is never interpreted as a function declaration) or auto x{expression};
respectively. The result is always a prvalue of an object type.
所以你的用法似乎被上面引用的声明所允许(根据 )。
Here 是您的代码的工作演示。请注意,在链接的演示中,只有使用 auto(x)
会产生错误,所有其他情况都可以正常工作。
另请注意,来自 PR105516:
auto(x);
is interpreted as auto x;
. Use +auto(x);
if you want that to be an expression.
If there is no ambiguity, then which priority comes first:
这是展示 C++ 如何成为一种上下文敏感语言 的示例之一。如果不了解其更广泛的上下文,就不能总是理解一个结构。考虑以下示例:
int main()
{
int x = 0 ;
int k ;
//------vvvvvvv----->here auto(x) is behaves as an expression as it is used as an expression
k = auto(x) ;
auto(p) ; //this a declaration and not an explicit case unlike the above
}
据我所知 the paper 除了允许 auto
作为 functional-style 显式转换中的类型说明符外,引入此功能并没有做任何进一步的相关更改。
所以凭直觉 auto
这里的行为应该与任何其他类型说明符的行为相同。
例如,将 auto
替换为 int
,预计所有这些情况都有效并且是 functional-style 显式转换,除了
int(x); // auto(x);
根据语法,这也可以是名为 x
的 int
类型(或占位符类型)变量的声明,声明符周围有括号且没有初始值设定项。
像往常一样,通过更喜欢将解释作为声明来消除语法歧义(参见 [stmt.ambig]/1). At least, I don't think that it should be different for auto
. A declaration with auto
placeholder type requires an initializer, which is not present in this interpretation, but according to [stmt.ambig]/3 消除歧义应该很早就完成并且纯粹是语法,即使它以 ill-formed 声明结束.我不完全确定,但我想这应该意味着 auto(x);
仍然应该作为声明来消除歧义。
我不知道为什么 Clang 会为许多其他行提供错误。我想该功能要么只实现了部分,要么这些是实现错误(这是未完成的标准修订版中的一个非常新的功能)。
我认为 auto(x)
(其中 x
实际上是一个标识符)在不同的上下文中仍然可以有不同的含义,因此在 C++23 中受制于 [dcl.ambig.res]。
不幸的是,歧义不太可能得到修复。在以下程序中(well-formed 自 C++11 起),auto(x) = Bar{};
被解释为声明。如果 auto(x)
是“固定的”,auto(x) = Bar{};
将成为一个表达式语句,这将改变现有的行为。
#include <cstdio>
struct Bar {
Bar()
{
std::puts("initialization");
}
};
struct Foo {
void operator=(Bar)
{
std::puts("assignment");
}
};
int main()
{
Foo x{};
{
auto(x) = Bar{}; // only prints "initialization"
}
}
我有一个简单的代码片段如下所示 (https://godbolt.org/z/cPT3PhYdj):
int main() {
int x = 1;
auto(1); // ok in GCC, error in Clang
auto{1}; // ok in GCC, error in Clang
static_cast<void>(auto(x)); // ok
auto{x}; // ok in GCC, error in Clang
auto(x); // both error in GCC an Clang
}
GCC 和 Clang 都发出错误显示:
// by GCC Trunk [-std=c++23]
<source>: In function 'int main()':
<source>:7:3: error: declaration of 'auto x' has no initializer
7 | auto(x); // why
| ^~~~
Compiler returned: 1
// by Clang Trunk [-std=c++2b]
<source>:3:8: error: expected unqualified-id
auto(1); // why
^
<source>:3:8: error: expected ')'
<source>:3:7: note: to match this '('
auto(1); // why
^
<source>:4:7: error: expected unqualified-id
auto{1}; // why
^
<source>:6:7: error: expected unqualified-id
auto{x}; // why
^
<source>:7:8: error: redefinition of 'x'
auto(x); // why
^
<source>:2:7: note: previous definition is here
int x = 1;
^
<source>:7:8: error: declaration of variable 'x' with deduced type 'auto' requires an initializer
auto(x); // why
^
6 errors generated.
Compiler returned: 1
如果 C++23 是实验性的,他们是否能够修复歧义或更改消歧,因为另一个
auto(expr)
被引入,或者只是保留它?这些表达式应该被解析为表达式语句中的显式类型衰减转换
auto(expr)
或auto{expr}
还是被解析为声明?如果没有歧义,那么哪个优先级在前:
auto(identifier)
为auto identifier
?, 或auto(identifier)
as cast expression?
auto ( expression ) (8) (since C++23) auto { expression } (9) (since C++23)
8,9) The
auto
specifier is replaced with the deduced type of the invented variablex
declared withauto x(expression);
(which is never interpreted as a function declaration) orauto x{expression};
respectively. The result is always a prvalue of an object type.
所以你的用法似乎被上面引用的声明所允许(根据 )。
Here 是您的代码的工作演示。请注意,在链接的演示中,只有使用 auto(x)
会产生错误,所有其他情况都可以正常工作。
另请注意,来自 PR105516:
auto(x);
is interpreted asauto x;
. Use+auto(x);
if you want that to be an expression.
If there is no ambiguity, then which priority comes first:
这是展示 C++ 如何成为一种上下文敏感语言 的示例之一。如果不了解其更广泛的上下文,就不能总是理解一个结构。考虑以下示例:
int main()
{
int x = 0 ;
int k ;
//------vvvvvvv----->here auto(x) is behaves as an expression as it is used as an expression
k = auto(x) ;
auto(p) ; //this a declaration and not an explicit case unlike the above
}
据我所知 the paper 除了允许 auto
作为 functional-style 显式转换中的类型说明符外,引入此功能并没有做任何进一步的相关更改。
所以凭直觉 auto
这里的行为应该与任何其他类型说明符的行为相同。
例如,将 auto
替换为 int
,预计所有这些情况都有效并且是 functional-style 显式转换,除了
int(x); // auto(x);
根据语法,这也可以是名为 x
的 int
类型(或占位符类型)变量的声明,声明符周围有括号且没有初始值设定项。
像往常一样,通过更喜欢将解释作为声明来消除语法歧义(参见 [stmt.ambig]/1). At least, I don't think that it should be different for auto
. A declaration with auto
placeholder type requires an initializer, which is not present in this interpretation, but according to [stmt.ambig]/3 消除歧义应该很早就完成并且纯粹是语法,即使它以 ill-formed 声明结束.我不完全确定,但我想这应该意味着 auto(x);
仍然应该作为声明来消除歧义。
我不知道为什么 Clang 会为许多其他行提供错误。我想该功能要么只实现了部分,要么这些是实现错误(这是未完成的标准修订版中的一个非常新的功能)。
我认为 auto(x)
(其中 x
实际上是一个标识符)在不同的上下文中仍然可以有不同的含义,因此在 C++23 中受制于 [dcl.ambig.res]。
不幸的是,歧义不太可能得到修复。在以下程序中(well-formed 自 C++11 起),auto(x) = Bar{};
被解释为声明。如果 auto(x)
是“固定的”,auto(x) = Bar{};
将成为一个表达式语句,这将改变现有的行为。
#include <cstdio>
struct Bar {
Bar()
{
std::puts("initialization");
}
};
struct Foo {
void operator=(Bar)
{
std::puts("assignment");
}
};
int main()
{
Foo x{};
{
auto(x) = Bar{}; // only prints "initialization"
}
}