演算子は単なる関数なので、問題は関係しません。あなたがここで望んでいるのは多重ディスパッチ(ダブル、この特定のケースでは、クリスチャンが正しく述べたように)です。言語サポートを必要とするものを含む実装および実行時の複雑さの点で、複数のアプローチがある(例えば、仮想関数パラメータおよびBjarne Stroustrupの対応する論文を参照)。
あなたがコアC++でこれを行うにしたい場合は、あなたが私の一般的な実装を見てみることを歓迎していると、必要なものをコピー:コードの https://ideone.com/uGue2K
使用法:
// C inherits from A, both have a static initializer that registers them and their base class(es)
struct print : Visitor2<A>
{
// Feel free to change the return type, but keep it consistent.
// Alternatively, you can call a lambda with the result.
static void v1(const A& a1, const A& a2, int i, int j)
{
std::cout << "A, A: "<< a1() << a2() << " " << i << " " << j << std::endl;
}
static void v2(const C& c1, const A& a2, int i, int j)
{
std::cout << "C, A: "<< c1() << a2() << " " << i << " " << j << std::endl;
}
// and so on...
print(int k_)
: k(k_)
{
add_visitor(v1, v2 /* ... */);
}
auto operator[](const A& a) { /* see in code */ };
};
int main()
{
print p(4); // p takes virtual A&, virtual A&, int, int.
const A& a = A();
const A& b = B();
p[a][a](1, 2);
p[c][a](2, 3);
}
提案コードとパターンを歓迎します。フォローしやすくするために、ビジターのoperator[](const A&)
がインプレースで実装されていますが、それは完全にVisitor2<A>
で実行できます。
Visitor2<A>
の代わりにVisitor< Visitor<A> >
を使用することはできません。外側一致が複数あり、最初に試した内側のものが失敗したときに外側のリゾルバに「バックトラック」しないようにすることができます。これは、複数の派遣の難しさを強調しています(クリスチャンが言及しています)。あなたはすべての潜在的な機能を世界的に見る必要があります。遅さと大規模なコンパイル単位を期待する。仕様にあってショートカットが見つからない場合にのみ実装します。
*「このようなことができるようになりたい」* - それ自体問題です。なぜあなたはこれを必要としますか?それは基本的に二重派遣の問題につながる。すなわち、機能の所望の実装はもはや* 1つ* 2つの*オブジェクトの動的なタイプに依存しない。この権利を得るには、開発の複雑さの面で多くの費用がかかり、ほとんど利益を得ることができません。私があなただったら、オペレータを完全に取り除くだけです。 –
'A'と' B'を比較したくない場合は、最初に 'A'が仮想'演算子==() 'を提供しているのはなぜですか? – Peter
Aのリストを持ち、BとCの操作を実行できるようにしたい。 – Znatte