自动推导可以隐式添加常量吗?
Can auto deduction add implicitly constness?
考虑以下示例:
#include <iostream>
#include <string>
struct foo { std::string value; };
inline foo bar() { return { "42" }; }
std::string my_func() {
auto &x = bar();
^^^^^^^^^^^^^^^^
return x.value;
}
int main() {
std::cout << my_func() << std::endl;
}
编译它 GCC and CLANG 会发出同样的错误,很可能是正确的:
error: invalid initialization of non-const reference of type 'foo&'
from an rvalue of type 'foo'
然而,令我惊讶的是它在 VC++2015 中编译并运行良好。
- 这是 VC++2015 的错误吗?
- 当语句使程序格式错误时,标准是否规定
auto
可以隐式地向对象添加 const
ness?
不,auto
不能添加常量。但是,MSVC++ 一直有一个扩展,非 const 左值引用可以绑定到右值。
我认为您可以使用 /Za
开关禁用此扩展程序。
Is this a bug of VC++2015?
该标准允许实现接受格式错误的代码作为扩展。然而,仍然需要实施才能发出诊断(这可能只是意味着 "emit a warning when certain flags are turned on")。
Does the standard dictates that auto
can add implicitly constness to an object when a statement renders the program ill-formed?
不,标准要求 auto
推导使用与模板参数推导相同的规则(初始化列表除外)。如果T&
不接受,那么auto&
也不会。
Is this a bug of VC++2015?
Redmond 的被告经常称它为 "feature",但它是编译器混乱中的一个完全愚蠢的错误(可以用 /Za
修复)。让我们看看为什么...
auto &x = bar();
好的,所以你打电话给 bar()
,不是吗?这会产生一个 rvalue
,即没有地址的对象。现在,您无法将 lvalue
(可以获取其地址的对象)引用 (a.k.a: &
) 绑定到 rvalue
。到目前为止,这就是您的代码非法的原因。
但是,C++ 语言中有一个特殊规则,允许 const lvalue
引用绑定到 rvalue
,从而有效地延长其生命周期。所以,这将是有效的代码...
const auto &x = foo();
编辑:顺便说一句...
Does the standard dictates that auto can add implicitly constness to an object when a statement renders the program ill-formed?
用非标准语 terminology/plain 英语表达,如果 T&
被拒绝,auto&
也会被拒绝。 CV 限定符(const
和 volatile
)是 而不是 从 auto
.
自动推导出来的
我希望这对您有所启发!
考虑以下示例:
#include <iostream>
#include <string>
struct foo { std::string value; };
inline foo bar() { return { "42" }; }
std::string my_func() {
auto &x = bar();
^^^^^^^^^^^^^^^^
return x.value;
}
int main() {
std::cout << my_func() << std::endl;
}
编译它 GCC and CLANG 会发出同样的错误,很可能是正确的:
error: invalid initialization of non-const reference of type 'foo&' from an rvalue of type 'foo'
然而,令我惊讶的是它在 VC++2015 中编译并运行良好。
- 这是 VC++2015 的错误吗?
- 当语句使程序格式错误时,标准是否规定
auto
可以隐式地向对象添加const
ness?
不,auto
不能添加常量。但是,MSVC++ 一直有一个扩展,非 const 左值引用可以绑定到右值。
我认为您可以使用 /Za
开关禁用此扩展程序。
Is this a bug of VC++2015?
该标准允许实现接受格式错误的代码作为扩展。然而,仍然需要实施才能发出诊断(这可能只是意味着 "emit a warning when certain flags are turned on")。
Does the standard dictates that
auto
can add implicitly constness to an object when a statement renders the program ill-formed?
不,标准要求 auto
推导使用与模板参数推导相同的规则(初始化列表除外)。如果T&
不接受,那么auto&
也不会。
Is this a bug of VC++2015?
Redmond 的被告经常称它为 "feature",但它是编译器混乱中的一个完全愚蠢的错误(可以用 /Za
修复)。让我们看看为什么...
auto &x = bar();
好的,所以你打电话给 bar()
,不是吗?这会产生一个 rvalue
,即没有地址的对象。现在,您无法将 lvalue
(可以获取其地址的对象)引用 (a.k.a: &
) 绑定到 rvalue
。到目前为止,这就是您的代码非法的原因。
但是,C++ 语言中有一个特殊规则,允许 const lvalue
引用绑定到 rvalue
,从而有效地延长其生命周期。所以,这将是有效的代码...
const auto &x = foo();
编辑:顺便说一句...
Does the standard dictates that auto can add implicitly constness to an object when a statement renders the program ill-formed?
用非标准语 terminology/plain 英语表达,如果 T&
被拒绝,auto&
也会被拒绝。 CV 限定符(const
和 volatile
)是 而不是 从 auto
.
我希望这对您有所启发!