簡體   English   中英

對多個類重用運算符<<

[英]Reuse an operator<< for several classes

我有兩個類(這是一個,從我實際更復雜的案例中摘錄)

class ClUInt {
public:
    ClUInt() : _i(2), _arr{1,2,3} {};
    ClUInt(const unsigned int ui) : _i(ui) {};
private:
    unsigned int _i;
    double _arr[3];
};

class ClInt {
public:
    ClInt() : _i(-2), _arr{-1,-2,-3} {};
    ClInt(const int i) : ClInt() { _i = i; };
private:
    int _i;
    double _arr[3];
};

它們非常相似,但一個使用int ,另一個使用unsigned int作為成員_i

我想重載operator<< ,例如,

std::ostream& operator<<(std::ostream& os, const ClInt & ci)
{
    cout << ci._i << endl;
    cout << ci._arr[0] << endl;
    return os;
}

假設我想要兩個類的“相同”重載。

怎么只寫一次,方便維護? 我想定義我自己的演員表,但我不確定這是要走的路......

筆記:

  1. 我沒有機會讓這兩個類共享繼承樹的任何部分。

  2. 它們實際上可能是struct ,因此如果隱私影響答案,則可以假設_i_arrpublic

  3. 在實際情況下,這兩個struct分別具有更多數量的有符號/無符號的“公共”成員。

使用帶有概念的模板:

#include <concepts>
#include <iostream>

template<typename T>
concept ClInteger = std::same_as<T, ClInt> || std::same_as<T, ClUInt>;

template <ClInteger T>
std::ostream& operator<<(std::ostream& os, const T & ci)
{
    std::cout << ci._i << '\n';
    std::cout << ci._arr[0] << '\n';
    return os;
}

請注意,此運算符必須是這些類的朋友才能訪問其私有字段。
居住

您可以嘗試使用 SFINAE 創建一個僅適用於這兩種類型的模板化operator<< 例如:

template <class T,
  std::enable_if_t<
      std::is_same<ClInt, std::decay_t<T>>::value
      or std::is_same<ClUInt, std::decay_t<T>>::value
    , int> = 0>
std::ostream & operator<< (std::ostream & out, T const & obj) {
  out << obj._i << '\n';
  out << obj._arr[0] << '\n';
  return out;
}

上面的示例適用於 C++14,但如果您將std::decay_t<T>替換為typename std::decay<T>::type ,則可以使其與 C++11 一起使用。

注意:我用'\\n'替換了std::endl ,因為您可能不想每次都刷新輸出流。 請參閱C++: "std::endl" 與 "\\n"

也許這只是巧合,但您的兩個班級共享很多。 那么,為什么不把它們變成模板:

template<typename integer_type>
class IntegerClass
{
    /// ... further code elided

    friend ostream& operator<<(ostream& out, IntegerClass const& obj)
    {
        return out
            << obj._i << endl
            << obj._arr[0] << endl;
    }
    integer_type _i;
    double _arr[3];
};

// optional typedefs
// These are a matter of taste, not actually mine.
typedef IntegerClass<unsigned int> ClUInt;
typedef IntegerClass<signed int> ClInt;

暫無
暫無

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

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