2017-05-05 4 views
1

私は暇な時間にC++について学んでおり、添え字/ []演算子をオーバーロードするクラスを実装しています。オペレータオーバーロードのコンテキストを具体的にする

myObject[i,j,...]、引数は、例えばstring Sまたはint S

Iを見つけることができる:ここで、Iは、添字演算子次のように(カンマで区切られた)2つの以上の引数を渡すことができるようにしたかったですC++では添字演算子が複数の引数を受け入れることはできません。しかし、私はthis threadにカンマ演算子をオーバーロードすることについて、その '問題'の代替解決策として読んだ。

この例では、コンマ演算子は2つのカスタムEnumで非常に固有のシグネチャを使用してオーバーロードされていますが、一般的な型ペアのコンマ演算子をオーバーロードすることはお勧めできません。場合)。

私の限られたC++知識のおかげで、コンマ演算子のオーバーロードを特定の状況やコンテキストに限定して使用することが可能かどうかが不思議に思えました。たとえば、添字演算子他の場所で干渉を引き起こすことなく、私が興味を持っている機能を私に与えてくれます。

答えて

1

通常の関数/演算子をコンテキストに限定することはできませんが、名前空間のためスコープで制限することはできます。代替として

enum class E {A, B}; 

struct C 
{ 
    int operator [](const std::pair<E, E>& p) const 
    { 
     return data[static_cast<int>(p.first) * 2 + static_cast<int>(p.second)]; 
    } 
    std::array<int, 4> data{{1, 2, 3, 4}}; 
}; 

namespace comma 
{ 
    std::pair<E, E> operator , (E lhs, E rhs) { return { lhs, rhs }; } 
} 

int main() 
{ 
    C c; 

    { 
     using namespace comma; // operator , is valid here. 

     std::cout << c[E::A, E::B] << std::endl; 
     auto p = (E::A, E::B); // but also here :/ p = {E::A, E::B} 
     static_cast<void>(p); 
    } 
    { 
     std::cout << c[E::A, E::B] << std::endl; // result in c[E::B] 
     auto p = (E::A, E::B); // p = E::B 
     static_cast<void>(p); 
    } 
} 

Demo

、あなたは(いくつかのパラメータを取ることができます)、通常の方法、operator()メソッドを使用して、引数としてstd::pair/std::tupleを使用する(つまり、呼び出しサイトで{}を囲む余分に必要となります)。

+0

これはクールです!ありがとう。したがって、名前空間を使用して、理論的には例えば'std :: pair オペレータ、(int lhs、int rhs){return {lhs、rhs}; }そのスコープの範囲外でカンマ演算子の他の用途を混乱させることなく、 – TBZ92

+0

'演算子'は、クラスまたは列挙型の少なくとも1つのパラメータを持つ必要があります。 'int' /' int'は不正です。 – Jarod42

0

いいえ特定のコンテキストに対してのみ演算子をオーバーロードすることはできません。あなたはそのオペレーターのタイプに基づいてその使用を制限することができます。

0

演算子をオーバーロードすると、この演算子で使用できる型が指定されます。したがって、クラス内で定義された型で設計することをお勧めします。

class YourClass 
{ 
public: 
class YourType{}; 
}; 

pair<YourClass::YourType, YourClass::YourType> operator , (YourClass::YourType p1, YourClass::YourType p2) 
{ 
    return make_pair(p1, p2); 
} 

しかし、何らかの一般化が必要な場合は、テンプレートとテンプレートの特殊化を使用できます。

+0

はい、これは私の質問のリンクされた例が提供するものです。私はそれが一般的な型の議論のために安全に行うことも可能かどうか疑問に思っていたが、これは不可能だと思う。 – TBZ92

関連する問題