2016-04-27 137 views
5

我想了解運算符重載如何工作的更多信息。運算符逗號重載

我明白,重載逗號運算符可能不是最好的主意,但這僅用於教學目的。

我期待下面的代碼使用我的重載操作符(我使用了括號,因爲我知道逗號操作符具有最低的優先級)來構造一個包含(1,2)的向量,然後調用向量的賦值操作符。

但是,我得到一個錯誤:

no known conversion from argument 1 from 'int' to 'const std::vector<int>&' 

我不明白爲什麼會這樣。 (1,2)應該構建一個向量,所以它不應該試圖從int轉換爲vector<int>

#include <vector> 
#include <utility> 

using std::vector; 
using std::move; 

template <typename T> 
vector<T> operator,(const T& v1, const T& v2) 
{ 
    vector<T> v; 
    v.push_back(v1); 
    v.push_back(v2); 
    return move(v); 
} 

int main() 
{ 
    vector<int> a; 
    a = (1,2); 
    return 0; 
} 
+0

「*所以它不應該試圖從一個int轉換爲一個向量?*」 - 這正是它試圖做的事情,但由於沒有隻有'int'的'vector'構造函數,它不會不知道該怎麼做,而這正是你所得到的錯誤信息,不是嗎? – Dolda2000

+2

當然不是。他沒有複製消息的那部分內容,說明它與嘗試將有效的賦值運算符('operator =')函數與對象'a'匹配失敗相關。 – Paulo1205

+0

@ Dolda2000:「*不存在僅用於int *的向量構造函數」 - 否,但是有一個接受'vector :: size_type'來代替(指定默認構造項的初始數目來填充向量),並且'int'可以被分配給'vector :: size_type'。然而,'vector'不能'int' /'size_type',只顯式*,這就是爲什麼'int'不能直接傳遞給'vector :: operator ='的原因。 –

回答

19

適用於整數的逗號運算符已經有一個內置的定義。您的模板甚至沒有運行重載解析,因爲除非至少有一個參數是用戶定義的類型,否則不能重載操作符。

你可以做這樣的事情:

template<typename T> 
struct vector_maker 
{ 
    std::vector<T> vec; 
    vector_maker& operator,(T const& rhs) { 
     vec.push_back(rhs); 
     return *this; 
    } 

    std::vector<T> finalize() { 
     return std::move(vec); 
    } 
}; 

int main() { 
    auto a = (vector_maker<int>(),1,2,3,4,5).finalize(); 
} 

或者看看Boost.Assign,這使得結構是這樣的:

std::vector<int> a; 
a += 1,2,3,4,5,6,7,8; 
2

的賦值的右手邊的表達式是簡單評估爲(1,2)並簡併爲(2)2,這是int

然後分配評估。左側是vector<int>。您正試圖將2(一個int)分配給a(一個vector<int>),並且由於沒有從intvector<>的轉換,您會收到錯誤消息。

您將無法使內置類型的運算符超載,例如int