提问人:RandomGuy 提问时间:10/14/2023 最后编辑:Jan SchultkeRandomGuy 更新时间:10/14/2023 访问量:111
如何std::cout<<具有许多(模棱两可的)用户定义转换函数的类型?
How to std::cout << a type which has many (ambiguous) user-defined conversion functions?
问:
在这里,我有一个类,它处理的大数远远超出了.它将其数据存储为 .现在我这里有很多很多转换器:c++
long long
std::string
class BigInt {
private:
std::string x;
public:
operator std::string() { return x; }
operator int() { return std::stoi(x); }
operator long long() { return std::stoll(x); }
operator unsigned long long() { return std::stoull(x); }
operator double() { return std::stod(x); }
operator long double() { return std::stold(x); }
...
BigInt(std::string a) : x(a) {}
BigInt(long long a) : x(to_string(a)) {}
...
}
int main() {
BigInt x = 10485761048576;
std::cout << x << std::endl; // Error!
}
但是发生的情况是我收到一个错误:
多个运算符与这些操作数匹配。
这基本上意味着该函数不知道选择哪个转换器。那么,在访问函数时,是否有一种“默认”转换器选择其中一个转换器作为默认转换器呢?std::cout
如果没有那种东西,那么我想每次我想将参数传递到某种重载函数时,我都必须调用类似的东西。std::cout << (std::string)x << std::endl;
答:
1赞
wohlstad
10/14/2023
#1
您可以为 以下 提供 std::ostream
运算符的
重载<<BigInt
std::ostream& operator<<(std::ostream& os, const BigInt& obj)
{
os << static_cast<std::string>(obj);
return os;
}
为了能够对对象使用转换运算符(如上所述,无论如何这是一个很好的做法),您还需要将它们标记为 const
,例如:const
operator<<
// -----------------------vvvvv--------------
operator std::string() const { return x; }
现在您可以使用:
int main()
{
BigInt x = 10485761048576;
std::cout << x << std::endl;
}
输出:
10485761048576
评论
0赞
RandomGuy
10/14/2023
等等,它真的不起作用......在我的编译器(MSVC)中,它告诉我,在链接过程中:运算符<<已经在BigNumbers.cpp中定义,找到了一个或多个乘法定义的符号。我认为这是因为我已经创建了从 BigInt 到 int 和 long long 的转换器等等?
1赞
wohlstad
10/14/2023
如果在头文件中定义,则将其设为 () 或仅在头 () 中放置声明,并将实现放在 cpp 文件中。operator<<
inline
inline std::ostream& operator<< ...
std::ostream& operator<<(std::ostream& os, const BigInt& obj);
0赞
RandomGuy
10/14/2023
谢谢,这确实解决了问题:将其标记为内联。这实际上是最简单的方法之一,不是吗
0赞
Swift - Friday Pie
10/14/2023
这仅仅是因为您的转换器是隐式的......他们优先于非成员运营商
0赞
Jan Schultke
10/14/2023
您可以将 简化为一行: .operator<<
return os << static_cast<std::string>(obj)
评论
explicit