Class 对象到字符串的隐式转换运算符
Implicit Conversion Operator for Class Objects to Strings
我正在了解有关隐式转换运算符的更多信息,并且我注意到隐式用户定义的字符串转换有些奇怪。下面是代码。
#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"
来解决。对于最后一个,您可能还想检查初始化列表。
关于当前编译错误:
编译错误是由代码 cout << abc
试图在类型 A
的 object 上使用运算符 << 引起的。但是,您没有重载此运算符。
在您的示例中,这可能类似于
friend std::ostream &operator<<(std::ostream &output, const A &a )
{
output << a.value;
return output;
}
即使您将 user-defined 转换为 std::string
,您仍然会遇到编译时错误。 link 解释的比我想象的要好 Why cannot use cout with user-defined conversion to std::string?
上面link的解释我是这样理解的:
string
header 为 operator<<
为 std::basic_ostream
定义了以下重载:
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>
的类型定义。
但是,如果转换是隐式的,则以下规则生效:
Type deduction does not consider implicit conversions (other than type
adjustments listed above): that's the job for overload resolution,
which happens later.
因此,编译器无法从 A
推导出函数的第二个参数(例如 const std::basic_string<CharT, Traits, Allocator>& str
)。但是,它可以为 string
推导出它,因此您可以像 static_cast<string>(abc)
一样将 abc
显式转换为 string
,这样就可以了。
我正在了解有关隐式转换运算符的更多信息,并且我注意到隐式用户定义的字符串转换有些奇怪。下面是代码。
#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"
来解决。对于最后一个,您可能还想检查初始化列表。
关于当前编译错误:
编译错误是由代码 cout << abc
试图在类型 A
的 object 上使用运算符 << 引起的。但是,您没有重载此运算符。
在您的示例中,这可能类似于
friend std::ostream &operator<<(std::ostream &output, const A &a )
{
output << a.value;
return output;
}
即使您将 user-defined 转换为 std::string
,您仍然会遇到编译时错误。 link 解释的比我想象的要好 Why cannot use cout with user-defined conversion to std::string?
上面link的解释我是这样理解的:
string
header 为 operator<<
为 std::basic_ostream
定义了以下重载:
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>
的类型定义。
但是,如果转换是隐式的,则以下规则生效:
Type deduction does not consider implicit conversions (other than type adjustments listed above): that's the job for overload resolution, which happens later.
因此,编译器无法从 A
推导出函数的第二个参数(例如 const std::basic_string<CharT, Traits, Allocator>& str
)。但是,它可以为 string
推导出它,因此您可以像 static_cast<string>(abc)
一样将 abc
显式转换为 string
,这样就可以了。