类对象到字符串的隐式转换运算符



我正在学习更多关于隐式转换运算符的知识,并且注意到字符串的隐式用户定义转换有一些奇怪之处。下面是代码。

#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
class A {
public:
A() {
*value = "YIKERS";
} 
operator string&() {
return *this->value;
}
string* value;
};

int main() {
A abc;
cout << abc << endl; 
// compile error: invalid operands to binary expression ('std::__1::ostream' (aka
// 'basic_ostream<char>') and 'A')
return 0;
}

关于我为什么会出现这个编译错误,有什么想法吗?我想这可能意味着对象没有被隐式转换为字符串?如果是,为什么不呢?有办法解决这个问题吗?转换运算符适用于其他数据类型,如int、float、char等。

首先,我认为您没有按预期使用std::string value。这会导致另一个编译错误(至少在gcc 10.2上(。看起来你想要一个字符串,而你正在使用一个指向字符串的指针。这可以通过用string value替换string* value、用operator string()替换operator string&()和用value = "YIKERS"替换*value = "YIKERS'来解决。对于最后一个,您可能还需要检查初始值设定项列表。

关于当前编译错误:

编译错误是由于代码CCD_ 8试图使用运算符<lt;在作为CCD_ 10类型的对象的CCD_。但是,您没有使此运算符过载。在您的示例中,这可能类似于

friend std::ostream &operator<<(std::ostream &output, const A &a ) 
{ 
output << a.value;
return output;            
}

即使您对std::string进行了用户定义的转换,您仍然会遇到编译时错误。这个链接比我想象的更好地解释了它为什么不能使用cout和用户定义的std::string转换?

这就是我如何理解上面链接的解释:

string标头为std::basic_ostreamoperator<<定义以下过载:

template <class CharT, class Traits, class Allocator>
std::basic_ostream<CharT, Traits>&
operator<<(std::basic_ostream<CharT, Traits>& os,
const std::basic_string<CharT, Traits, Allocator>& str);

此外,std::string实际上是std::basic_string<char>的typedef。

然而,如果转换是隐含的,则以下规则生效:

类型推导不考虑隐式转换(类型除外上面列出的调整(:这就是解决过载的工作,这将在以后发生。

因此,编译器无法从A推导出函数的第二个参数(例如const std::basic_string<CharT, Traits, Allocator>& str(。然而,它可以为string推导它,这样您就可以像static_cast<string>(abc)一样将abc显式转换为string,这将起作用。

最新更新