質問

Visual Studio 10(ベータ2)を試している間にいくつかの簡単なポイントコードを書いています。SFINAEが作動するはずのこのコードにヒットしましたが、そうではないようです:

template<typename T>
struct point {
    T x, y;
    point(T x, T y) : x(x), y(y) {}
};

template<typename T, typename U>
struct op_div {
    typedef decltype(T() / U()) type;
};

template<typename T, typename U>
point<typename op_div<T, U>::type>
operator/(point<T> const& l, point<U> const& r) {
    return point<typename op_div<T, U>::type>(l.x / r.x, l.y / r.y);
}

template<typename T, typename U>
point<typename op_div<T, U>::type>
operator/(point<T> const& l, U const& r) {
    return point<typename op_div<T, U>::type>(l.x / r, l.y / r);
}

int main() {
    point<int>(0, 1) / point<float>(2, 3);
}

これによりerror C2512: 'point<T>::point' : no appropriate default constructor available

が得られます

ベータ版であることを考えると、私はオンラインコモーコンパイラで簡単な健全性チェックを行い、同じエラーと一致するため、この動作は正しいようですが、理由はわかりません。

この場合、いくつかの回避策は、単にdecltype(T() / U())をインライン化するか、ポイントクラスにデフォルトコンストラクターを与えるか、完全な結果式でdecltypeを使用することですが、エラーを単純化しようとしてこのエラーが発生しましたデフォルトのコンストラクター*を必要としないバージョンのop_divを使用しているため、動作するだけでなくC ++の理解を修正したい。

ありがとう!


*:オリジナル:

template<typename T, typename U>
struct op_div {
    static T t(); static U u();
    typedef decltype(t() / u()) type;
};

error C2784: 'point<op_div<T,U>::type> operator /(const point<T> &,const U &)' : could not deduce template argument for 'const point<T> &' from 'int'を与えるもの、およびpoint<T> / point<U>オーバーロードを与えるもの。

役に立ちましたか?

解決

100%確実ではありません。どちらの方が良いかを判断するには、コンパイラーが両方のオーバーロードをインスタンス化する必要があるようですが、他のop_divをT = intU = point<float>でインスタンス化しようとすると、SFINAEでカバーされないエラーが発生します(エラーはこの場合、op_divにはタイプはありませんが、そのタイプを判別することはできません)。

2番目のタイプがポイント(boost::disable_if)の場合、2番目のオーバーロードを無効にしようとすることができます。

また、動作するように思われるのは、戻り型の宣言を延期することです(op_div構造体は廃止しますが、コンパイラーがサポートしているC ++ 0x機能によって異なります):

template<typename T, typename U>
auto
operator/(point<T> const& l, point<U> const& r) -> point<decltype(l.x / r.x)> {
    return {l.x / r.x, l.y / r.y};
}

template<typename T, typename U>
auto
operator/(point<T> const& l, U const& r) -> point<decltype(l.x / r)> {
    return {l.x / r, l.y / r};
}

他のヒント

あなたのエラーはここにあると思います:

template<typename T>
struct point {
    T x, y;
    point(T x, T y) : x(x), y(y) {}
};

構造体の定義を次のように変更します。

template<typename T>
struct point<T> {
    T x, y;
    point(T x, T y) : x(x), y(y) {}
};

ジェネリック型Tを使用する場合は、定義で指定する必要があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top