2016-06-12 6 views
1

たとえば、の要素を持つ数学的ベクトルを表すクラスVec<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のようなものをサポートしていますか?

EDIT:

だから、ここに私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+されています。残念ながら、v + {1, 2}は文法規則のためのC++で整形式ではありません

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.equals({8, 9})についてどのように

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

答えをありがとう。もう一つの選択肢は、 'add'や' isEqualTo'のような関数を作ることです。次のようにイニシャライザリストを簡単に渡すことができます: 'v.isEqualTo({1,2,3});' –

1

?また、v + {1, 2, 3, 4}は可能ではありませんが、多くのベクトル行列の実装(intではなく、v + (V(1), 2, 3, 4)のような特定の型の場合)でカンマ演算子をオーバーロードする可能性があります。

+0

あなたの 'equals'のようなメソッドを使うことを選んだら、受け入れられた答えに対する私のコメントを見てください。 ところで、(OpenCVのような)いくつかのライブラリでコンマの実装を見たことがありますが、私はむしろこの設計から離れています。特に明白なインターフェースではない) –

関連する問題