Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将左值绑定到右值引用--g++;缺陷_C++_Compiler Errors - Fatal编程技术网

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
,而你从casted
char
构造
,我无法想象为什么这个问题会被否决…@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"} );