ambiguous overload for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and '__int128') win MinGW

huangapple go评论194阅读模式
英文:

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 &lt;iostream&gt;

void f()
{
    __int128_t val = 1;
    
    std::cout &lt;&lt; val;
}

and getting the following compiler error:

error: ambiguous overload for &#39;operator&lt;&lt;&#39; (operand types are &#39;std::ostream&#39; {aka &#39;std::basic_ostream&lt;char&gt;&#39;} and &#39;__int128&#39;)
[build]    16 |         std::cout &lt;&lt; val;
[build]       |         ~~~~~~~~~ ^~ ~~~
[build]       |              |       |
[build]       |              |       __int128
[build]       |              std::ostream {aka std::basic_ostream&lt;char&gt;}error: ambiguous overload for &#39;operator&lt;&lt;&#39; (operand types are &#39;std::ostream&#39; {aka &#39;std::basic_ostream&lt;char&gt;&#39;} and &#39;__int128&#39;)
[build]    16 |         std::cout &lt;&lt; val;
[build]       |         ~~~~~~~~~ ^~ ~~~
[build]       |              |       |
[build]       |              |       __int128
[build]       |              std::ostream {aka std::basic_ostream&lt;char&gt;}

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_toperator<< 的重载,这在标准中没有提到,并且不跨平台,它是特定于GCC编译器的。

因此,编译器试图将该值隐式转换为其他类型,如 intunsigned intlong 等。结果,这种转换会导致歧义,因为可以将 __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&lt;&lt; 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&amp; operator&lt;&lt;(std::ostream&amp; o, const __int128_t&amp; x) {
    if (x == std::numeric_limits&lt;__int128_t&gt;::min()) return o &lt;&lt; &quot;-170141183460469231731687303715884105728&quot;;
    if (x &lt; 0) return o &lt;&lt; &quot;-&quot; &lt;&lt; -x;
    if (x &lt; 10) return o &lt;&lt; (char)(x + &#39;0&#39;);
    return o &lt;&lt; x / 10 &lt;&lt; (char)(x % 10 + &#39;0&#39;);
}

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 &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;limits&gt;

std::ostream&amp; operator &lt;&lt; (std::ostream&amp; os, __int128_t val)
{
    std::string result;
    bool is_negative = val &lt; 0;
    if (is_negative)
    {
        val *= -1;
    }

    do
    {
        result.push_back((val % 10) + &#39;0&#39;);
        val /= 10;
    }
    while (val != 0);

    if (is_negative)
    {
        result.push_back(&#39;-&#39;);
    }

    std::reverse(result.begin(), result.end());
    return (os &lt;&lt; result);
}

int main()
{
    __int128_t val = std::numeric_limits&lt;int64_t&gt;::max();
    
    std::cout &lt;&lt; (val * 900000);
    return 0;
}

huangapple
  • 本文由 发表于 2023年6月8日 21:53:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76432589.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定