C++ 为什么会存在两个只因返回常量不同的隐式转换?

C++ 为什么会存在两个只因返回常量不同的隐式转换?,c++,visual-studio-2010,implicit-conversion,C++,Visual Studio 2010,Implicit Conversion,考虑以下代码: #include <string> class WrapperString { public: WrapperString(const std::string& str) : str_(str) {} operator std::string() const { return str_; } operator const std::string() const { return str_; } std::string ge

考虑以下代码:

#include <string>

class WrapperString
{
public:
    WrapperString(const std::string& str) : str_(str) {}

    operator std::string() const { return str_; }
    operator const std::string() const { return str_; }

    std::string get() const { return str_; }
    // error C2373: 'WrapperString::get' : redefinition; different type modifiers
    // const std::string get() const { return str_; }

private:
    std::string str_;
};

int main (int, char *[])
{
    WrapperString w( "Hello" );
    std::string foo = w; // disabling either implicit conversion makes this work
    return 0;
}
#包括
类包装器字符串
{
公众:
WrapperString(const std::string&str):str(str){}
运算符std::string()常量{return str}
运算符const std::string()const{return str}
std::string get()常量{return str_;}
//错误C2373:“WrapperString::get”:重新定义;不同的类型修饰符
//const std::string get()const{return str_;}
私人:
std::string str;
};
int main(int,char*[])
{
包装字符串w(“你好”);
std::string foo=w;//禁用任何一种隐式转换都可以实现此功能
返回0;
}
既然这两个隐式转换只因其
const
不同,为什么
WrapperString
实际编译?不能通过声明命名方法来实现此结果

顺便说一句,这里是VS2010


EDIT:为了清楚起见,我添加了
get()
方法作为逻辑反例,解释了为什么有两个隐式转换没有意义。

这是对两种不同类型的转换,其中一种是const,另一种不是。康斯特内斯是这个类型的一部分

这与禁止具有返回不同类型的相同签名的函数不同

既然两个隐式转换的常量不同,为什么WrapperString实际上是编译的呢

返回类型不是唯一的区别:
operator std::string
operator const std::string
是这两个函数的名称,在这种情况下,它们恰好不同于
get
成员函数的名称

$3[basic]/4:
“名称是使用[…]转换函数id”

$12.3.2.1[class.conv.fct]/1:

conversion-function-id:
    operator conversion-type-id
如果愿意,可以使用普通函数调用语法通过这些名称调用它们

 std::string s1 = w.operator std::string();
 std::string s2 = w.operator const std::string();
 std::string s3 = w.get(); // which get?

不同转换函数的不同名称与其说是基本原理,不如说是实现细节。@BenVoigt也许——相同的语义可以用不同的术语指定(例如,在指定什么可以重载,什么不能重载时,为转换函数做一个特殊的例外)——但现在就是这样指定的(据我所知)。