這是正確的,您的operator==
未被調用的原因是因爲缺少const
標識符。在這種情況下,文字5
無法作爲變量參考傳遞給參數T& val
。但是,這不是完整的故事。
正如您所指出的那樣,即使函數未被調用,代碼仍然會編譯並運行。
您的代碼仍然工作的原因是由於conversion operator:operator T(){ return value; }
。
轉換運算符允許從一種類型到另一種類型的隱式轉換。例如:
struct Number {
Number(int x) : value(x) { }
operator int() { return value; }
private:
int value;
};
int main() {
Number n(5);
int x = n; // 5 -- operator int() at work
int y = n + x; // 10 -- operator int() at work
Number z = x + y; // 15 -- Number(int) at work
cout << x <<" "<< y <<" "<< z << endl;
return 0;
}
這裏,operator int()
允許n
到轉換成int
用於分配給x
和要轉換爲int
用於添加與x
(所得int
然後分配給y
),而一元構造Number(int)
允許x + y
的結果轉換回Number
。
在代碼中,5 == x
仍然編譯因爲tType<int>
x
經由其operator int()
成員函數轉換爲int
,然後將該所得的int
抵靠字面5
比較。
但是,這可能不是一個非常好的類設計。例如,爲了比較兩個tType<T>
s,其中一個需要投入T
。
template <class T>
bool operator==(const T& val, const tType<T>& tval) {
cout << "operator==(const T& val, const tType<T>& tval) was called." << endl;
return(val == tval.value);
}
//...
cout << (tType<int>() == tType<int>()) << endl; // calls operator==(const T&, const tType<T>&)
你寧願有兩個tType<T>
秒的operator==
。
另一個甚至更大的問題是,這是不是對稱的:
cout << (x1 == 5) << endl; // calls operator==(int,int) (the built-in function)
哎呀!
要解決所有這些問題,有一個非常簡單的設計解決方案。這是從斯科特邁耶斯的書Effective C++ Third Edition
(一本驚人的書)。
不是轉換回T
與轉換運算符,類應該包括一個隱含的一元構造函數T
的轉換高達tType<T>
s,而應該準確地申報一個operator==
爲tType<T>
S:
template <class T>
class tType
{
public:
tType<T>(const T &val) : value(val) { } // unary non-explicit constructor
tType<T> operator=(const tType<T> &val){ value = val.value; return *this; } // only need one
T val() { return value; }
private:
T value; // Note also value is private (encapsulation)
};
template<class T>
bool operator==(const tType<T>& a, const tType<T>& b) { return (a.val() == b.val()); }
重要更改:
- 添加了一個構造函數,它具有單個值;這允許將
T
s轉換成tType
s。
- 刪除賦值運算符采取
T
S(因爲現在我們可以將它們轉換爲tType
秒。
- 只能有一個平等的運營商,它有兩個
const tType<T>&
S,這意味着operator==
可以處理的T
S和tType<T>
小號的任意組合(或,甚至更好,任何可轉換成任何一種的東西)