簡體   English   中英

C++ 模板友元運算符重載

[英]C++ template friend operator overloading

我的代碼有什么問題?

template<int E, int F>
class Float
{
 friend Float<E, F> operator+ (const Float<E, F> &lhs, const Float<E, F> &rhs);
};

G++ 只是不斷警告:

float.h:7: warning: friend declaration 'Float<E, F> operator+(const Float<E, F>&, const Float<E, F>&)' declares a non-template function

float.h:7: warning: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) -Wno-non-template-friend disables this warning

如警告說明中所述,我嘗試add <> after the function name here ,但是 g++ 給了我一個錯誤。

我用 clang++ 編譯了代碼,很好,根本沒有警告。

這只是關於語言的一個棘手方面的警告。 當你聲明一個friend函數時,它不是聲明所在類的成員。為了方便你可以在那里定義它,但它實際上屬於命名空間。

在類模板中聲明一個不是模板的友元函數,仍然在命名空間中聲明了一個非模板函數。 它既不是類的成員,也不是模板。 但是,它是由類模板生成的。

從模板生成非模板函數有點模糊。 例如,您不能在class塊之外為該函數添加聲明。 因此,您也必須在class塊中定義它,這是有道理的,因為類模板會生成它。

關於朋友的另一個棘手的事情是class Float {}中的聲明沒有在命名空間中聲明函數。 您只能通過依賴於參數的含義重載解析來找到它,即指定參數具有Float類型(或引用或指針)。 這對於operator+來說不是問題,因為無論如何它都可能被重載,並且除了用戶定義的類型之外永遠不會調用它。

作為潛在問題的示例,假設您有一個轉換構造函數Float::Float( Bignum const& ) 但是Bignum沒有operator+ (對不起,人為的例子。)你想依靠operator+(Float const&, Float const&)來進行Bignum加法。 現在my_bignum + 3將無法編譯,因為這兩個操作數都不是Float因此它找不到friend函數。

或許,您無需擔心,只要所討論的函數是operator

或者,您也可以將friend更改為模板。 在這種情況下,它必須在class {}之外定義,並在它之前聲明,而不需要在內部聲明和定義。

template<int E, int F> // now this is a template!
Float<E, F> operator+ (const Float<E, F> &lhs, const Float<E, F> &rhs);

template<int E, int F>
class Float
{
  // deduce arguments E and F - this names operator+< E, F >.
 friend Float<E, F> operator+<> (const Float<E, F> &lhs, const Float<E, F> &rhs);
};

這是一個相當古老的話題,但我認為聲明運算符的最簡單方法是在 Float 類中定義它。

template<int E, int F>
class Float
{
public:
    friend Float operator+ (const Float &lhs, const Float &rhs)
    {
        // Whatever you need to do.
    }
};

語法更容易編寫和理解,並且它的工作方式完全相同(除了它會被內聯),它不會是一個成員函數。

MSDN:在類聲明中定義的友元函數不考慮在封閉類的范圍內; 它們在文件范圍內。

您需要完全按照警告說的做:

template<int E, int F>
Float<E, F> operator+ (const Float<E, F> &lhs, const Float<E, F> &rhs);

template<int E, int F>
class Float
{
 friend Float<E, F> operator+<> (const Float<E, F> &lhs, const Float<E, F> &rhs);
};

這將運算符模板的完全特化聲明為類模板的特定實例的朋友。 在對問題的評論中,UncleBens 友好地提供 了一個鏈接,解釋了為什么這如此復雜。

暫無
暫無

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

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