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也许——相同的语义可以用不同的术语指定(例如,在指定什么可以重载,什么不能重载时,为转换函数做一个特殊的例外)——但现在就是这样指定的(据我所知)。