[英]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.