2011-10-22 57 views
11

有这样的代码:改变返回值

#include <iostream> 
#include <string> 

int returnnumber() { return 2; } 
std::string returntext() { return "siema"; } 

int main() { 

    std::cout << (returntext() += "cze") << std::endl; // siemacze 
    //std::cout << (returnnumber() += 2) << std::endl; error: lvalue required as left operand of assignment 

    return 0; 
} 

为什么是有可能改变的std :: string的返回值,但不是int?

回答

10

因为std::string是一个类型,其定义的+=运算符作为成员函数。

并且该标准允许您在rvalues上调用成员函数。

的是一个愚蠢的后果是,

struct S { int x; }; 
S foo() { return S(); } 

int main() 
{ 
    foo() = S(); // OK, uses member assignment operator. 
    foo().x = 666; // !Nah, can't assign to rvalue of built-in type. 
} 

编译结果:

 
Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2 
Copyright 1988-2008 Comeau Computing. All rights reserved. 
MODE:strict errors C++ C++0x_extensions 

"ComeauTest.c", line 7: error: expression must be a modifiable lvalue 
     foo().x = 666; // !Nah, can't assign to rvalue of built-in type. 
    ^

1 error detected in the compilation of "ComeauTest.c". 

然而,编译器不同(或用于不同)他们是如何严格执行这一微妙的规则,或如果有的话。

欢呼&心连心,

+0

好吧,但对于'int',运算符'+ ='也被定义。 – Vlad

+0

@downvoter:为什么? – Vlad

+0

@anonymous downvoter:请解释你的downvote,以便其他人可以从你的洞察中受益,或忽略一些愚蠢的原因。 –

2

的内置类型必须是一个可修改左值而是一个函数的返回值始终是一个右值如果函数赋值运算符的左侧不返回引用类型。

operator+=std::string的成员函数,您可以调用类类型的右值上的成员函数。

+0

我想知道,为什么这样的不一致? – Vlad

+0

你的意思是“一个赋值操作符的左侧?” –

+0

@VaughnCato:是的,我做过。谢谢。 –

1

出于同样的原因

std::string("siema") += "cze"; 

作品。

您正在构建一个新对象并将其应用于operator +=(其中std::string)。

尝试此操作将无法正常工作,因为您的函数返回rvalue。这将是这样的:

2 += 2 

你可以围绕玩具与此:

#include <iostream> 
#include <string> 

int& returnnumber() { int * k = new int; *k = 2; return *k; } 
std::string returntext() { return "siema"; } 

int main() { 

    std::cout << (returntext() += "cze") << std::endl; // siemacze 
    std::cout << (returnnumber() += 2) << std::endl; //no error 
    std::string("siema") += "cze"; 
    return 0; 
} 

但是,这将导致内存泄漏,所以不这样做。这只是一个概念证明,返回lvalue将工作。

+0

嗨Luchian :)不'returntext'也返回一个右值? – Vlad

+0

Charles Bailey写道:如果函数没有返回引用类型,函数的返回值总是一个右值。然后returntext返回右值或左值? – scdmb

+0

我很困惑,关闭做一些阅读:) –

0

returntext()返回std::string,可以在后面的阶段修改+=operator。但是,虽然returnnumber()返回int,但函数本身返回2,这是由const int决定的,并且不可更改,这就是编译器抱怨的原因。