4

私は次の問題に直面しています: クラス V (ベクトルなど) があり、そこから CI と I (const_iterator と iterator を考えてください) の 2 つのクラスを生成できます。const V がある場合は、CI しか生成できません (ここでも iterator と const_iterator を考えてください)。

基本的に、(const V& v) を (CI ci) に、(V& v) を (I i) に置き換えたいと思います。さらに、V obj を I または CI を期待する関数に直接渡すことができるようにしたいため、V および const V から CI および I への暗黙的な変換が行われます。

私が直面している問題は、オーバーロードされた関数は (const V& v) と (V& v) を区別できますが、V obj を渡すときに (CI ci) と (I i) を「区別」できないことです。

コード内:

struct V {};

struct I 
{
    I( V& v ){}
};

struct CI
{
    CI( const V& v ){} //I would like to say const only 
};

void fun( I i )
{
    double x = 1.0;
}
void fun( CI ci )
{
    double x = 2.0;
}

void fun2( V& v )
{
    double x = 1.0;
}
void fun2( const V& v )
{
    double x = 2.0;
}

CI と I でコンストラクターを定義する代わりに、V で変換演算子を定義できたことに注意してください (同等ですか?)。

V v;
const V cv;

fun2( v );
fun2( cv );

fun( v ); //AMBIGUOUS!
fun( cv );

余分な間接化を追加せずにこの問題を解決する方法はありますか (つまり、fun 関数は変更できず、v を fun に直接渡す必要がありますが、他のすべてを自由に変更できます)。

助けてくれてありがとう!

4

2 に答える 2

4

ここで必要なのは、明示的なコンストラクターです。

struct I 
{
    explicit I( V& v ){}
};

struct CI
{
    explicit CI( const V& v ){} //I would like to say const only 
};

あまりにも多くの C++ プログラマーが、コンストラクターの明示的なキーワードを見落としています。パラメーター化された単項コンストラクターはすべて、既定で明示的にする必要があります。暗黙的なコンストラクターは、このようなあいまいさの問題を引き起こすだけでなく、問題のある非常に非効率的なコードに簡単につながる可能性のある、非常に間抜けで迂遠な変換プロセスにつながります。

これで設定が完了し、あいまいさの問題が解決されました。明示的なコンストラクターがないと、このあいまいさの問題を防ぐことはできません。

クライアント コードについては、変換について明示的になるように変更する必要があります。

V v;
const V cv;

fun2( I(v) );
fun2( CI(cv) );

fun( I(v) );
fun( CI(cv) );

このような構文は、I または CI のオブジェクトを構築するために必要になりますが、それは良いことです。あいまいさの問題を誤って導入することはもうありません。

于 2010-06-25T01:51:11.930 に答える
0

typedefsだけを使用するのはどうですか?

typedef V& I;
typedef const V& CI;

編集:

いいえ。コメントを参照してください:)

于 2010-06-24T18:03:47.730 に答える