問(wèn)題描述
我想知道為什么隱式類型轉(zhuǎn)換不適用于類模板上的外部運(yùn)算符重載.這是工作的非模板版本:
I would like to know why implicit type conversion doesn't work with outside operator overloading on class templates. Here is the working, non-templated version:
class foo
{
public:
foo() = default;
foo(int that)
{}
foo& operator +=(foo rhs)
{
return *this;
}
};
foo operator +(foo lhs, foo rhs)
{
lhs += rhs;
return lhs;
}
正如預(yù)期的那樣,以下幾行編譯正確:
As expected, the following lines compile correctly:
foo f, g;
f = f + g; // OK
f += 5; // OK
f = f + 5; // OK
f = 5 + f; // OK
另一方面,當(dāng)類 foo
被聲明為一個(gè)簡(jiǎn)單的模板時(shí):
On the other hand, when class foo
is declared as a simple template like this:
template< typename T >
class foo
{
public:
foo() = default;
foo(int that)
{}
foo& operator +=(foo rhs)
{
return *this;
}
};
template< typename T >
foo< T > operator +(foo< T > lhs, foo< T > rhs)
{
lhs += rhs;
return lhs;
}
以下幾行編譯出錯(cuò):
foo< int > f, g;
f = f + g; // OK
f += 5; // OK
f = f + 5; // Error (no match for operator+)
f = 5 + f; // Error (no match for operator+)
我想了解為什么編譯器 (GCC 4.6.2) 無(wú)法使用類模板版本的轉(zhuǎn)換構(gòu)造函數(shù)執(zhí)行隱式類型轉(zhuǎn)換.這是預(yù)期的行為嗎?除了手動(dòng)創(chuàng)建所有必要的重載之外,是否有任何解決方法?
I would like to understand why the compiler (GCC 4.6.2) is unable to perform implicit type conversion using the converting constructor for the template version of the class. Is that the expected behaviour? Apart from manually creating all the necessary overloads, is there any workaround for this?
推薦答案
它不正常工作的原因是隱式類型轉(zhuǎn)換(即通過(guò)構(gòu)造函數(shù))在模板參數(shù)推導(dǎo)期間不適用.但是如果你讓外部操作符成為朋友,那么它就可以工作,因?yàn)轭愋?T 是已知的,允許編譯器調(diào)查可以轉(zhuǎn)換什么來(lái)使參數(shù)匹配.
The reason it does not just work is that implicit type conversions (that is, via constructors) do not apply during template argument deduction. But it works if you make the outside operator a friend since then the type T is know, allowing the compiler to investigate what can be casted to make the arguments match.
我根據(jù)您的示例(但刪除了 C++11 內(nèi)容)制作了一個(gè)示例,其靈感來(lái)自 Scott Meyers Effective C++(第 3 版)中的第 46 項(xiàng)(有理數(shù)類).您的問(wèn)題幾乎與該項(xiàng)目完全匹配.Scott 還指出……這種朋友的使用與類的非公共部分的訪問(wèn)無(wú)關(guān)."
I made an example based on yours (but removed C++11 stuff), inspired by Item 46 (a rational number class) in Scott Meyers Effective C++ (ed 3). Your question is almost an exact match to that item. Scott also notes that ... "this use of friend is not related to the access of non-public parts of the class."
這也將允許混合使用 foo<T>, foo 等等,只要可以添加 T 和 U 等等
This will also allow work with mixes of foo< T >, foo< U > etc as long as T and U can be added etc.
另看這篇文章:C++加法重載歧義
#include <iostream>
using namespace std;
template< class T >
class foo
{
private:
T _value;
public:
foo() : _value() {}
template <class U>
foo(const foo<U>& that) : _value(that.getval()) {}
// I'm sure this it can be done without this being public also;
T getval() const { return _value ; };
foo(const T& that) : _value(that) {}
friend const foo operator +(foo &lhs,const foo &rhs)
{
foo result(lhs._value+rhs._value);
return result;
};
friend const foo operator +(foo &lhs,const T &rhsval)
{
foo result(lhs._value+rhsval);
return result;
};
friend const foo operator +(const T &lhsval,foo &rhs)
{
foo result(lhsval+rhs._value);
return result;
};
friend foo& operator +=(foo &lhs,const foo &rhs)
{
lhs._value+=rhs._value;
return lhs;
};
friend std::ostream& operator<<(std::ostream& out, const foo& me){
return out <<me._value;
}
};
int main(){
foo< int > f, g;
foo< double > dd;
cout <<f<<endl;
f = f + g;
cout <<f<<endl;
f += 3 ;
cout <<f<<endl;
f = f + 5;
cout <<f<<endl;
f = 7 + f;
cout <<f<<endl;
dd=dd+f;
cout <<dd<<endl;
dd=f+dd;
cout <<dd<<endl;
dd=dd+7.3;
cout <<dd<<endl;
}
這篇關(guān)于為模板類重載運(yùn)算符時(shí)的隱式轉(zhuǎn)換的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!