gcc 'operator&lt;&lt;'的二义性重载(操作数类型为'std::ostream' {aka 'std::basic_ostream< char>'}和'__int128')win MinGW

dbf7pr2w  于 2023-06-23  发布在  其他
关注(0)|答案(2)|浏览(164)

我尝试用MinGW(x86_64-13.1.0-release-win32-seh-msvcrt-rt_v11-rev 1)编译以下代码:

#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>}

为什么是模棱两可的?

编辑1

在线编译器中的GCC也有同样的错误。

EDIT2

下面的代码也是同样的结果:

void f1 (uint64_t val) {}
void f1 (int32_t val) {}

void f()
{
    __int128_t val = 1;
    
    f1(val);
}
ht4b089n

ht4b089n1#

该错误意味着operator<<没有重载__int128_t,这在标准中没有提到,也不是跨平台的,它特定于GCC编译器。
因此,编译器会尝试隐式地将值转换为其他类型,如intunsigned intlong等。因此,这种转换会引起歧义,因为有许多类型可以转换为__int128_t,并且这些类型有多个运算符重载。
据我所知,打印__int128_t的唯一方法是编写自己的运算符重载。Here is a link,您可以在其中找到创建此类重载的代码段。其中一个可能的变体(从给定链接中的答案复制)看起来像这样:

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库来使用任意大小的整数。

ykejflvf

ykejflvf2#

编写自己的运算符来进行转换和打印。

#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;
}

相关问题