1

私はこのコードを持っています:

template <class T>
class Something
{
    T val;
public:
    inline Something() : val() {}
    inline Something(T v) : val(v) {}
    inline T& get() const { return val; }

    inline Something& operator =(const Something& a) { val = a.val; return *this; }
};

typedef Something<int> IntSomething;
typedef Something<const int> ConstIntSomething;

class Other
{
public:
    IntSomething some_function()
    {
        return IntSomething(42);
    }

    ConstIntSomething some_function() const
    {
        return ConstIntSomething(42);
    }
};

void wtf_func()
{
    Other o;
    ConstIntSomething s;
    s = o.some_function();
}

ただし、コンパイラはOther::some_function()inの間違ったオーバーロードwtf_func()(つまり、非 const のもの) を選択します。どうすればこれを修正できますか? の名前を変更できない理由があることに注意してくださいOther::some_function()

4

5 に答える 5

2

oconst 修飾されていないため、非 constsome_functionが選択されます。const 修飾されたオーバーロードを選択する場合は、const 修飾子をo次のように追加する必要があります。

Other o;
Other const& oref(o);
ConstIntSomething s;
s = oref.some_function();

オーバーロードの解決が発生すると、コンパイラはo.some_function()部分式のみを調べます。関数呼び出しの前後のコンテキストを調べて、何か他のものを選択するかどうかを決定することはありません。さらに、メンバー関数の戻り値の型は、オーバーロードの解決中に考慮されません。

でオーバーロードを使用する(あまり良くない) か、非明示的なコンストラクターを使用する (より良い)かのいずれかで、IntSomethingが に暗黙的に変換可能であることがより理にかなっていることに注意してください。ConstIntSomethingoperator ConstIntSomething()IntSomethingConstIntSomething(IntSomething const&)ConstIntSomething

于 2011-08-16T18:17:21.980 に答える
1

間違ったオーバーロードを選択することはありません。const-ness は、 であるかどうかによって解決されthisますconst。あなたの場合、oは non-constであるため、非constオーバーロードが選択されます。

への const-reference を作成することで、これをハックできますo

const Other &o2 = o;
s = o2.some_function();

しかし、実際には、おそらく でオーバーロードを検討する必要がありますSomething。たとえば、現在これを行うことはできません。

IntSomething x;
ConstIntSomething y;
y = x;

これは正しく聞こえません。非 const ref に const ref を使用することを許可してはならないのはなぜですか?

于 2011-08-16T18:16:47.790 に答える
1

オブジェクトは、関数を呼び出すためのオブジェクトであるo必要があります。それ以外の場合、コンパイラは関数の非 const バージョンを正しく選択します。constconst

于 2011-08-16T18:17:14.003 に答える
0

C++0x 標準ライブラリのコンテナーにある新しい動作をコピーすることもできます。vector などのコンテナーにはメンバーがcbegin()ありcend()、コンテナーが const であるかどうかに関係なく、const_iterator を返しますbegin()end()

class Other {
    // Rest of other
public:
    // No overload for non-const
    // Even if called with a non const Other, since this member is marked
    // const, this will be of type Other const * in all cases and will call
    // the const qualified overload of some_function.
    ConstIntSomething csome_function() const
    {
        return some_function();
    }
};
于 2011-08-16T18:33:13.330 に答える
0

コンパイラは、になるオブジェクトの constness に基づいて、使用するオーバーロードを選択しますthis。次のコマンドを使用して、目的のバージョンを呼び出させることができますstatic_casts = static_cast<const Other&>(o.some_function());

于 2011-08-16T18:21:39.757 に答える