C++ 将左值绑定到右值引用--g++;缺陷
作为回答,我想发布以下代码(也就是说,我想发布基于此想法的代码):C++ 将左值绑定到右值引用--g++;缺陷,c++,compiler-errors,C++,Compiler Errors,作为回答,我想发布以下代码(也就是说,我想发布基于此想法的代码): 无法使用MSVC 11.0进行编译,是否使用MinGW 4.7.1进行编译,这是正确的?我没有检查规范,但我猜char可以自动转换为int。由于您无法分配任何内容(它是r值),因此将传递r值给类型为int(更明确地说是(int)c值)的临时变量。我发现N3290(与c++11标准相同)包含将双值和绑定到int左值生成的右值的非规范性示例,以及§8.5.3 “如果T1是与T2相关的引用,且该引用是右值引用, 初始值设定项表达式不得
无法使用MSVC 11.0进行编译,是否使用MinGW 4.7.1进行编译,这是正确的?我没有检查规范,但我猜
char
可以自动转换为int
。由于您无法分配任何内容(它是r值),因此将传递r值给类型为int
(更明确地说是(int)c
值)的临时变量。我发现N3290(与c++11标准相同)包含将双值和绑定到int
左值生成的右值的非规范性示例,以及§8.5.3
“如果T1是与T2相关的引用,且该引用是右值引用,
初始值设定项表达式不得为左值。”
据报道,这些规则的设计是为了避免低效的额外复制。虽然我看不出这样的复制是如何无法优化的。不管怎么说,不管理由是否合理——当然,这似乎不是一个合理的结果!——允许使用以下代码,并使用MSVC 11和MinGW g++4.7进行编译:
struct Foo {};
struct Bar { Bar( Foo ) {} };
void ugh( Bar&& ) {}
int main()
{
Foo o;
ugh( o );
}
显然,MSVC 11不允许左值->右值转换是错误的。
编辑:我了解到有关于此问题的缺陷报告。2012年2月的结论是,当前的行为规范是“正确的”,大概是关于它在多大程度上反映了意图。然而,据报道,委员会仍在讨论这一问题,大概是关于意图的实用性。大概你同意这是有效的
void foo( double ) {} // pass-by-value
int main()
{
char ch = '!';
foo( ch );
}
有一个从char
到double
的隐式转换,因此该函数是可行的
在您编辑的问题中的示例中也是如此,有一个隐式转换生成一个临时变量(即右值),右值引用参数绑定到该临时变量。如果愿意,可以显式转换:
void foo( double&& ) {} // pass-by-reference
int main()
{
char ch = '!';
foo( double(ch) );
}
但在这种情况下,这并没有改变任何事情。如果double
->char
只能显式转换(例如,对于具有显式构造函数或显式转换运算符的类类型),但double
到char
是一种有效的隐式转换,则这是必要的
您正在考虑的“右值引用不能绑定到左值”规则指的是将T&
绑定到T
左值,并且该规则没有被破坏,因为双值&&
没有绑定到char
,它绑定到通过隐式转换创建的临时值
该规则的存在不仅是为了防止不必要的额外复制,而且是为了解决以前规则中存在的真正安全问题,请参阅
编辑:委员会询问这种行为是否可取(见),并决定是的,这种行为是有意且正确的。用于达到该位置的一个参数是,在当前规则下,此代码更有效:
std::vector<std::string> v;
v.push_back("text");
当构造函数不显式时,显式构造std::string
是没有意义的。我希望从显式/隐式构造函数中得到一致的行为,并且我希望第一个<代码> PuxSuffue/Cuff>示例更有效。< /P>没有从“代码> char < /C++ >到int >代码>的隐式转换(来自C,我期望这个)?@ H2CO3:在C++中,您可以在int >代码> > <代码> char < /C>作为参数类型。所以,不,在这个上下文中没有转换。或者,我看不出如何(正确地)调用它。@Cheersandhth.-Alf:你可以超载,但你仍然可以自动施法。也就是说,如果你有void函数(char c){}
,它将被收集,但你从int&
构造Boxed
,而你从castedchar
构造,我无法想象为什么这个问题会被否决…@H2CO3:我后面跟着一个连续的否决票。他或她将其限制在足够低的频率,使其不会被SO机制自动固定。偶尔出现的连环事件在一定程度上弥补了这一缺陷。:-)因为这个答案,我更新了这个问题,加入了一个带有double&&
的例子char
->int
是与char
->double
不同类型的转换(标准中的一组不同规则)。所以我认为这个新的例子澄清了一点:机制不能是自动向上转换到int
@chearsandhth.-Alf:但是转换char
->double
仍然是合法的,所以类型(double)c
的值仍然是有效的r值。1)N3290是c++11标准,这是一份由国家机构投票并作为标准重新发布的文件。2)如果Bar b=o代码>可以,为什么ugh(o)
也可以?您将获得到临时条的隐式转换,并且右值引用可以绑定到临时条。第一个相当于Bar b=Bar(o)
,第二个相当于ugh(Bar(o))
,只是允许隐式转换,并且Foo
->Bar
可以隐式转换,就像char
->double
void foo( double&& ) {} // pass-by-reference
int main()
{
char ch = '!';
foo( double(ch) );
}
std::vector<std::string> v;
v.push_back("text");
v.push_back( std::string{"text"} );