簡體   English   中英

使用 class 模板重載 operator<< 時會發生奇怪的事情

[英]Wierd stuff happens when overloading operator<< with a class template

這是我期望實現的功能:

darray<int> a;
a.push_back(1);
a.push_back(2);
a.push_back(3);
std::cout << a << std::endl; // displays: {1, 2, 3}

我的實施:

template <typename T>
class darray
{
private:
    long m_capacity;
    long m_size;
    T* m_data;
    void resize();

public:
    // constructors & destructors
    darray();

    // operations
    void push_back(T);
    std::ostream& print(std::ostream&) const;
    template<typename U> friend std::ostream& operator<<(std::ostream& os, U const& ar);
};

template<typename T>
std::ostream& darray<T>::print(std::ostream& os) const
{
    os << "{ ";
        for (size_t i = 0; i < m_size; i++)
        {
            os << m_data[i] << ", ";
            if ( i == m_size - 1 )
                os << m_data[i];
        }
        os << " }\n";
        return arr;
}

template<typename U>
std::ostream& operator<<(std::ostream& os, U const& obj)
{
    return obj.print(os);
}

產生錯誤:

error: ambiguous overload for ‘operator<<’ (operand types are ‘std::ostream’ {aka ‘std::basic_ostream<char>’} and ‘const char [66]’)

但是,當我更改 operator<< 的參數以接受darray<U>時,它工作正常:

template<typename U>
std::ostream& operator<<(std::ostream& os, darray<U> const& obj)
{
    return obj.print(os);
}

我在這里錯過了什么?

更新:

我也嘗試這樣做,在定義和實現中將參數更改為darray<U>類型,但它仍然會產生相同的錯誤:

template <typename T>
class darray
{
private:
    long m_capacity;
    long m_size;
    T* m_data;
    void resize();

public:
    // constructors & destructors
    darray();

    // operations
    void push_back(T);
    std::ostream& print(std::ostream&) const;
    template<typename U> friend std::ostream& operator<<(std::ostream& os, darray<U> const& ar);
};

template<typename T>
std::ostream& darray<T>::print(std::ostream& os) const
{
    os << "{ ";
        for (size_t i = 0; i < m_size; i++)
        {
            os << m_data[i] << ", ";
            if ( i == m_size - 1 )
                os << m_data[i];
        }
        os << " }\n";
        return os;
}

template<typename U>
std::ostream& operator<<(std::ostream& os, darray<U> const& obj)
{
    return obj.print(os);
}

在你的darray<T>::print function 中,如果你改變

os << m_data[i] << ", ";

os << m_data[i];
os << ", ";

然后編譯器不會抱怨並且工作正常。 我不知道為什么。

模板類中的友元函數必須在 class 聲明中定義。 這是我發現讓朋友 function 正確接受具有預期模板的模板化 class 實例的唯一方法。

所以在這里我會寫:

...
friend std::ostream& operator<<(std::ostream& os, darray<T> const& ar) {
    ar.print(os);
    return os;
}
...

但要注意:您的 class 包含一個指向分配的 memory 的原始指針,它可能在 class 析構函數中被刪除。 根據五的規則,您必須明確聲明(或刪除)復制/移動構造函數和賦值運算符。

暫無
暫無

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

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