問題描述
我的代碼有什么問題?
template<int E, int F>
class Float
{
friend Float<E, F> operator+ (const Float<E, F> &lhs, const Float<E, F> &rhs);
};
G++ 只是不斷警告:
G++ just keeps warning:
float.h:7: 警告:友元聲明‘Float
float.h:7: 警告:(如果這不是您想要的,請確保已經聲明了函數模板,并在此處的函數名稱后添加 <>)-Wno-non-template-friend 禁用此警告
我試圖添加<>在警告說明中提到的函數名稱之后
,但是 g++ 給了我一個錯誤.
I tried to add <> after the function name here
as mentioned in the warning note, but g++ gives me an error.
我用clang++編譯了代碼,很好,完全沒有警告.
I compiled the code with clang++, it was fine, no warning at all.
推薦答案
這只是關于語言的一個棘手方面的警告.當你聲明一個 friend
函數時,它不是聲明所在類的成員.為了方便你可以在那里定義它,但它實際上屬于命名空間.
It's just a warning about a tricky aspect of the language. When you declare a friend
function, it is not a member of the class the declaration is in. You can define it there for convenience, but it actually belongs to the namespace.
在類模板中聲明一個不是模板的友元函數,仍然在命名空間中聲明了一個非模板函數.它既不是類的成員,也不是模板.但是,它是由類模板生成的.
Declaring a friend function which is not a template, inside a class template, still declares a non-template function in the namespace. It is neither a member of the class, nor itself a template. However, it is generated by the class template.
從模板生成非模板函數有點模糊.例如,您不能在 class
塊之外為該函數添加聲明.因此,您還必須在 class
塊中定義它,這是有道理的,因為類模板會生成它.
Generating non-template functions from a template is a bit hazy. For example, you cannot add a declaration for that function outside the class
block. Therefore you must define it inside the class
block as well, which makes sense because the class template will generate it.
關于朋友的另一個棘手的事情是class Float {}
中的聲明沒有在命名空間中聲明函數.您只能通過依賴于參數的含義重載解析來找到它,即指定參數具有 Float
類型(或引用或指針).這對于 operator+
來說不是問題,因為無論如何它都可能被重載,并且除了用戶定義的類型之外永遠不會調用它.
Another tricky thing about friends is that the declaration inside class Float {}
does not declare the function in the namespace. You can only find it through argument-dependent meaning overload resolution, i.e. specifying an that an argument has type Float
(or a reference or pointer). This is not an issue for operator+
, as it is likely to be overloaded anyway, and it will never be called except for with user-defined types.
舉一個潛在問題的例子,假設你有一個轉換構造函數Float::Float(Bignum const&)
.但是Bignum
沒有operator+
.(對不起,人為的例子.)您想依靠 operator+(Float const&, Float const&)
來進行 Bignum
加法.現在 my_bignum + 3
將無法編譯,因為兩個操作數都不是 Float
,所以它找不到 friend
函數.
For an example of a potential issue, imagine you have a conversion constructor Float::Float( Bignum const& )
. But Bignum
does not have operator+
. (Sorry, contrived example.) You want to rely on operator+(Float const&, Float const&)
for Bignum
addition. Now my_bignum + 3
will not compile because neither operand is a Float
so it cannot find the friend
function.
也許,您無需擔心,只要所討論的函數是 operator
.
Probably, you have nothing to worry about, as long as the function in question is an operator
.
或者,您也可以將 friend
更改為模板.在這種情況下,它必須在 class {}
塊的外部定義,并在它之前聲明,而不需要在內部聲明和定義.
Or, you can change the friend
to be a template as well. In that case, it must be defined outside the class {}
block, and declared before it, instead of needing to be declared and defined inside.
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);
};
這篇關于C++ 模板友元運算符重載的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!