簡體   English   中英

使用重載運算符 '<<' 不明確

[英]Use of overloaded operator '<<' is ambiguous

我正在編寫一個類float32x4_t來模擬 x86 平台上的 ARM NEON 數據類型。 它的對象中有 4 個元素。

我想coutfloat32x4_t實例(打印出逗號分隔4種元素),但我的重載函數無法編譯。

我的代碼是:

#include <iostream>

struct float32x4_t
{
    float val[4];
    float& operator [] (int i) {
        return val[i];
    }
    const float& operator [] (int i) const {
        return val[i];
    }
    int size() const {
        return 4;
    }
};


template<class T>
std::ostream & operator << (std::ostream & os, const T& v)
{
    for (int i=0; i<v.size(); i++) {
        os << v.val[i] << ", ";
    }
    os << std::endl;
    return os;
}

/// @ingroup add
/// r[i] = a[i] + b[i]
static inline float32x4_t vaddq_f32(float32x4_t a, float32x4_t b)
{
    float32x4_t r;
    for (int i=0; i<4; i++) {
        r[i] = a[i] + b[i];
    }
    return r;
}

#include <stdio.h>

int main(int argc, char** argv)
{
    float32x4_t v1 = { 1.0, 2.0, 3.0, 4.0 };
    float32x4_t v2 = { 1.0, 1.0, 1.0, 1.0 };
    float32x4_t sum = vaddq_f32(v1, v2);
    std::cout << sum << std::endl;

    return 0;
}

整個錯誤是這樣的:

/home/zz/work/neon_pedal/neon_pedal.h:25:24: error: use of overloaded operator '<<' is ambiguous (with operand types 'std::basic_ostream<char>::__ostream_type' (aka 'basic_ostream<char>') and 'const char [3]')
        os << v.val[i] << ", ";
        ~~~~~~~~~~~~~~ ^  ~~~~
/home/zz/work/neon_pedal/main.cpp:18:15: note: in instantiation of function template specialization 'operator<<<float32x4_t>' requested here
    std::cout << sum << std::endl;
              ^
/usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/ostream:565:5: note: candidate function [with _Traits = std::char_traits<char>]
    operator<<(basic_ostream<char, _Traits>& __out, const char* __s)
    ^
/usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/ostream:548:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>]
    operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s)
    ^
/usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/ostream.tcc:321:5: note: candidate function [with _CharT = char, _Traits = std::char_traits<char>]
    operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)
    ^
/home/zz/work/neon_pedal/neon_pedal.h:22:16: note: candidate function [with T = char [3]]
std::ostream & operator << (std::ostream & os, const T& v)

如何解決此編譯錯誤?

注意:這里重載的operator <<與模板一起使用,這是因為將不僅僅是float32x4_t類型。 會有諸如float32x2_tint8x8_tint16x8_t等。

您的模板operator <<試圖為所有內容提供重載; 不僅僅是您的類型(因此意外匹配是模棱兩可的)。

有很多方法可以解決這個問題,但是由於您已經定義了自己的類型,並且整個目標是最小化您必須編寫以匹配的operator <<重載的數量,請考慮通用 TxN 模板,編寫一個(單數)重載,然后將您的真實類型別名為自然進化。

#include <iostream>
#include <array>

template<class T, size_t N = 4>
struct TxN
{
    T val[N];

    TxN() = default;

    T& operator[](size_t i)
    {
        return val[i];
    }

    T const& operator[](size_t i) const
    {
        return val[i];
    }

    size_t size() const
    {
        return N;
    }

    // there are at least three different ways to do this operator, but
    //  this is the easiest, so I included below.
    friend std::ostream& operator <<(std::ostream& os, TxN<T,N> const& t)
    {
        os << t.val[0];
        for (size_t i=1; i<N; ++i)
            os << ',' << t.val[i];
        return os;
    }
};

// now creating TypeN shrouds is trivial.
using float32x4_t = TxN<float, 4>;
using int16x8_t = TxN<short,8>;

/// @ingroup add
/// r[i] = a[i] + b[i]
static inline float32x4_t vaddq_f32(float32x4_t a, float32x4_t b)
{
    float32x4_t r;
    for (int i=0; i<4; i++) {
        r[i] = a[i] + b[i];
    }
    return r;
}

int main(int argc, char** argv)
{
    float32x4_t v1 = { 1.0, 2.0, 3.0, 4.0 };
    float32x4_t v2 = { 1.0, 1.0, 1.0, 1.0 };
    float32x4_t sum = vaddq_f32(v1, v2);
    std::cout << sum << '\n';

    int16x8_t i0 = { 1,2,3,4,5,6,7,8 };
    std::cout << i0 << '\n';

    return 0;
}

輸出

2,3,4,5
1,2,3,4,5,6,7,8

您正在嘗試為所有類型重載<<運算符。 因此,如果有一種類型的<<運算符已經在 std 命名空間中重載,它將是模棱兩可的,因為編譯器不知道選擇哪一個,是你的重載還是 std 命名空間中的重載。

 for (int i=0; i<v.size(); i++) {
    os << v.val[i] << ", ";
 }

具體來說, const char[] = ", "導致了這個問題,因為 std 命名空間中已經存在重載。 請注意,您也在調用os << std::endl但您使用std::是明確的,因此沒有歧義。 如果您想使用std命名空間中存在的ostream重載(我假設您這樣做),則無法使您的模板化重載可行。
你可以在你的結構中聲明一個朋友重載。

friend std::ostream & operator << (std::ostream & os,const float32x4_t & self){
         ...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM