2016-06-12 48 views
1

假設我正在開發一個類Vec<T>,它表示一個數學向量,其元素類型爲T過載類型轉換爲初始化列表

爲了方便我創建了一個需要std::initializer_list構造:

Vec(std::initializer_list<T> l) 
    : size(l.size()) 
{ 
    data = new T[size]; 
    std::copy(l.begin(), l.end(), data); 
} 

所以,現在我可以做以下的事情:

v += Vec<int>({ 1, -1 }); 
bool equal = (v == Vec<int>({ 8, 9 })); 

等等......不過,這將是巨大的,如果我可以寫得更短,更清潔:

v += { 1, -1 }; 
bool equal = v == { 8, 9 }; 

我該如何實現這樣的行爲?我想我可以將類型轉換運算符重載到std::initializer_list,但它甚至被認爲是正常的做法嗎?編譯時間和性能有多糟糕,甚至可以工作?

std::vector怎麼樣,它支持類似於C++ 11中的東西嗎?

編輯:

所以,這裏是我的operator+=

Vec<T> & operator+=(const Vec<T> &v) 
{ 
    assert(size == v.size); 
    for (int i = 0; i < size; ++i) 
     data[i] += v.data[i]; 
    return *this; 
} 

中註釋的答案是正確的,initializer_list實際上賦值運算符之後的工作原理:

v += {2, 3}; 
v -= {2, 3}; 

我試着寫這樣的東西:

v = v + {2, 3}; 

這就是爲什麼它不起作用。

所以,結論是:你可以在賦值和複合賦值運算符之後像這樣使用它,但是對於二進制算術運算符和比較它不起作用,我正確嗎?我想創建自定義文字也不是一個選項。

順便問一下,怎麼樣:

const Vec<float> a{ 1.01, 2.02 }; // error: conversion from 'double' to 'float' requires a narrowing conversion test_app 
const Vec<float> b{ 1.01f, 2.02f }; // works, obviously 

我能做些什麼,以使隱式轉換在第一種情況?

EDIT2

這裏是operator+

friend Vec<T> operator+(Vec<T> v, const Vec<T> &w) 
{ 
    v += w; // reuse compound assignment 
    return v; // return the result by value (uses move constructor) 
} 
+1

顯示你的'operator + ='。這應該已經按照您的描述工作了。 –

+1

'v == {8,9}'在語法上無效。 – cpplearner

+0

['operator + ='just works](http://rextester.com/NBE83364),沒有額外的努力。我想大多數其他運營商也會這樣。 'operator =='是一個例外;在頂部,我不太清楚爲什麼它在這裏很特別。 –

回答

1

不幸的是,v + {1, 2}是不是在C++對語法規則結構良好表達。對於每個操作數,大多數二元運算符僅僅使用表達式,並且支撐列表不是表達式。複合賦值運算符+=是特殊的,因爲賦值也接受初始化子句的右側操作數,所以v += {1, 2}恰好工作。

一些替代方案:

operator+(v, {1, 2}) 
v + Vec<int>({1, 2}) 
+0

感謝您的回答。我認爲另一個選擇是創建像add或isEqualTo這樣的函數,在這裏你可以很容易地傳遞初始化列表,如下所示: 'v.isEqualTo({1,2,3});' –

1

如何v.equals({8, 9})?另外,雖然v + {1, 2, 3, 4}不可能,但您可能仍會像許多向量矩陣實現那樣重載逗號運算符(不適用於int,但對於特定類型,如:v + (V(1), 2, 3, 4),如果您喜歡,則添加宏)。

+0

是的,我已經選擇像你的'等號'一樣的方法,看看我的評論接受的答案。 順便說一句,我已經在一些庫中看到了逗號實現(比如OpenCV),但我寧願遠離這種設計。不是一個特別明顯的界面) –