2012-06-19 11 views
0

假设我们需要一些类来包装std :: string,除了所有其他细节外,它还提供了一个自动转换回std :: string的类型转换运营商:引用临时类型,它是由类型运算符创建的

class MyWrappedString { 
    std::string m_value; 
    /* ... */ 
public: 
    inline operator std::string() const { 
     return m_value; 
    } 
}; 

因此,运营商将返回字符串包裹对象的副本

但是,为什么下面的代码看似正确?

MyWrappedString x; 
const std::string& y = x; 
// now, y should be a reference to a temporary, right? 
std::cout << "y is: " << y << std::endl; 

转换运算符将返回m_value的临时副本,所以const std::string& y = x将创建到临时副本的引用。

为什么这样吗?我记得有一些引用对象的生命周期延长,但我不确定。

第二个问题:是否有可能有一个类型转换运算符返回一个const引用?

例如为:

inline operator const std::string &() const { 
    return m_value; 
} 

所以,上面的代码没有对临时复制工作吗?

PS:这个问题有点相关:Lifetime of temporaries,但仍然是一个不同的问题。

+0

如果您有两个单独的问题,请创建两个单独的帖子。 –

+1

关于与临时参考的const引用的生存期有关的问题Herb Sutter:http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/ –

+0

@BenjaminLindley :是的,但是很难解释它的背景。所以,回答问题1的人可能也会回答问题2 :) – Frunsi

回答

2

const引用保持基准活着(即使它会常出去超出范围),直到const引用超出范围

对于第二个问题:是的,你可以返回一个const引用,并且函数的返回值必须被分配到const引用

+0

好吧。 '运算符const std :: string&()const'工作(在VS2010和gcc4中)。我没有想到,但它只是起作用。尽管如此,人们不能同时拥有(有和没有参考)。谢谢! – Frunsi

+0

@Frunsi:我相信没有隐式类型转换......但是如果你打算提供它们,在你的情况下最好提供'const std :: string&',因为它可以让调用者决定他们是否想要复制字符串或不。 –

+0

@DavidRodríguez-dribeas:是的,没错,我也不相信隐式类型转换。但在我的特殊用例中,这非常方便。然而,我仍然非常惊讶,返回一个const引用的类型转换运算符正常工作。我相信,任何编译器都很难支持这些(因为引用不仅仅是类型,而且具有特殊的含义,比如它的扩展生命周期等......) – Frunsi

相关问题