英文:
ambiguous overload for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and '__int128') win MinGW
问题
我正在尝试使用MinGW (x86_64-13.1.0-release-win32-seh-msvcrt-rt_v11-rev1)编译以下代码:
#include <iostream>
void f()
{
__int128_t val = 1;
std::cout << val;
}
并且收到以下编译器错误:
error: ambiguous overload for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and '__int128')
[build] 16 | std::cout << val;
[build] | ~~~~~~~~~ ^~ ~~~
[build] | | |
[build] | | __int128
[build] | std::ostream {aka std::basic_ostream<char>}error: ambiguous overload for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and '__int128')
[build] 16 | std::cout << val;
[build] | ~~~~~~~~~ ^~ ~~~
[build] | | |
[build] | | __int128
[build] | std::ostream {aka std::basic_ostream<char>}
为什么会产生歧义?
EDIT1
在在线编译器中使用GCC也出现相同的错误。
EDIT2
在以下代码中也出现相同的结果:
void f1(uint64_t val) {}
void f1(int32_t val) {}
void f()
{
__int128_t val = 1;
f1(val);
}
英文:
I am trying to compile the following code with MinGW (x86_64-13.1.0-release-win32-seh-msvcrt-rt_v11-rev1):
#include <iostream>
void f()
{
__int128_t val = 1;
std::cout << val;
}
and getting the following compiler error:
error: ambiguous overload for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and '__int128')
[build] 16 | std::cout << val;
[build] | ~~~~~~~~~ ^~ ~~~
[build] | | |
[build] | | __int128
[build] | std::ostream {aka std::basic_ostream<char>}error: ambiguous overload for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and '__int128')
[build] 16 | std::cout << val;
[build] | ~~~~~~~~~ ^~ ~~~
[build] | | |
[build] | | __int128
[build] | std::ostream {aka std::basic_ostream<char>}
Why is it ambiguous?
EDIT1
The same error with GCC in online compilers.
EDIT2
The same result with the following code:
void f1 (uint64_t val) {}
void f1 (int32_t val) {}
void f()
{
__int128_t val = 1;
f1(val);
}
答案1
得分: 2
这个错误意味着没有针对 __int128_t
的 operator<<
的重载,这在标准中没有提到,并且不跨平台,它是特定于GCC编译器的。
因此,编译器试图将该值隐式转换为其他类型,如 int
、unsigned int
、long
等。结果,这种转换会导致歧义,因为可以将 __int128_t
转换为许多类型,并且对于这些类型有多个运算符重载。
据我所知,打印 __int128_t
的唯一方法是编写自己的运算符重载。这里有一个链接,可以找到创建这种重载的代码片段。其中一个可能的变体(从给定链接中的答案中复制)如下所示:
std::ostream& operator<<(std::ostream& o, const __int128_t& x) {
if (x == std::numeric_limits<__int128_t>::min()) return o << "-170141183460469231731687303715884105728";
if (x < 0) return o << "-" << -x;
if (x < 10) return o << (char)(x + '0');
return o << x / 10 << (char)(x % 10 + '0');
}
但是,如果在您的代码中必须使用如此大的数值,最好使用跨平台库,而不是特定于编译器的类型。例如,您可以使用一个 BigInt 库来使用任意大小的整数。
英文:
The error means that there are no overload of operator<<
exactly for __int128_t
, which is not mentioned in standard and which is not cross-platform, it is specific to the GCC compiler.
For this reason, the compiler tries to implicitly convert the value to other types like int
, unsigned int
, long
, etc. As a result, this conversion causes ambiguity, because there are many types to which it is possible to convert __int128_t
, and there are multiple operator overloads for those types.
As far as I know, the only way to print __int128_t
is to write your own operator overload. Here is a link for another question, where you can find code snippets for creating such an overload. One of the possible variants (copied from the answer in the given link) looks like this:
std::ostream& operator<<(std::ostream& o, const __int128_t& x) {
if (x == std::numeric_limits<__int128_t>::min()) return o << "-170141183460469231731687303715884105728";
if (x < 0) return o << "-" << -x;
if (x < 10) return o << (char)(x + '0');
return o << x / 10 << (char)(x % 10 + '0');
}
But, if in your code you have to use such big numbers, it is better to use cross-platform libraries, not compiler-specific types. For example, you can use a BigInt library for usage of arbitrary-sized integers.
答案2
得分: 2
写入您自己的运算符来执行转换和打印。
```cpp
#include <iostream>
#include <algorithm>
#include <limits>
std::ostream& operator << (std::ostream& os, __int128_t val)
{
std::string result;
bool is_negative = val < 0;
if (is_negative)
{
val *= -1;
}
do
{
result.push_back((val % 10) + '0');
val /= 10;
}
while (val != 0);
if (is_negative)
{
result.push_back('-');
}
std::reverse(result.begin(), result.end());
return (os << result);
}
int main()
{
__int128_t val = std::numeric_limits<int64_t>::max();
std::cout << (val * 900000);
return 0;
}
英文:
Write your own operator to do the conversion and printing.
#include <iostream>
#include <algorithm>
#include <limits>
std::ostream& operator << (std::ostream& os, __int128_t val)
{
std::string result;
bool is_negative = val < 0;
if (is_negative)
{
val *= -1;
}
do
{
result.push_back((val % 10) + '0');
val /= 10;
}
while (val != 0);
if (is_negative)
{
result.push_back('-');
}
std::reverse(result.begin(), result.end());
return (os << result);
}
int main()
{
__int128_t val = std::numeric_limits<int64_t>::max();
std::cout << (val * 900000);
return 0;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论