0

short-vector クラスに vector-op-scalar 演算子を実装しているときに問題が発生しました。コードは次のようにリストされます。

template<class T>
class Vec3
{
    Vec3& operator*=( const T& rhs );
};
template<class T>
Vec3<T> operator*( const Vec3<T>& lhs, const T& rhs );
Vec3<float> a;
a*=3; // right 
a*3; // wrong

さて、私は本当に驚いたのですが、operator*= の場合、予想どおり、定数の整数 3 が自動的に float に変換されましたが、operator* の場合はそうではなく、コンパイル エラーが発生しました。

エラー C2782: 'Vec3 operator *(const Vec3 &,T)': テンプレート パラメーター 'T' があいまいです

main.cpp(162) : 「operator *」の宣言を参照してください。「int」または「float」にすることができます

私はこれについて本当に混乱していて、なぜそれが起こるのか分かりません。

4

3 に答える 3

1
template<class T>
Vec3<T> operator*( const Vec3<T>& lhs, const T& rhs );

lhs が Vec3 で rhs が int の場合、コンパイラはテンプレート化された関数のどのバージョン (int バージョンまたは float バージョン) を使用するかを混乱させます。書いてみてくださいa * 3.0f。operator* をクラスに直接追加することもできます。この方法では、コンパイラが型のメソッドを呼び出し、Vec3<float>アスタリスクの右側の型が常に float に変換されます。

于 2013-06-25T07:23:05.027 に答える
1

最初の ( *=) では、Tテンプレート パラメーターは変数の宣言時に既に解決されているため、関数は既に署名付きで作成されてVec3& operator*=( const float& rhs )おり、int.

2 番目の例では、コンパイラはテンプレート パラメーターに基づいて適切な関数を作成しようとしていますが、同じテンプレート パラメーターに対してforとfloatfor の2 つの異なる型を取得しているため、関数の作成方法がわかりません。サイン。lhsintrhs

于 2013-06-25T07:24:07.097 に答える
1

メンバー演算子を呼び出すと、シグネチャは既にコンパイラに認識されています

Vec3& operator*=( const float& rhs );

と の間で暗黙的な変換を実行する必要がintありfloatます。それで問題ありません。

template を呼び出すときは、 and を推測するoperator*必要があります。これは、署名内の の使用ごとに同じタイプに推測できる場合にのみ成功します。ここでは型変換は行われません。コンパイラは、それが1 回と2 回であることを認識しているため、エラーが発生します。TTfloatint

1 つの回避策は、2 つの異なるテンプレート パラメーターを使用してフリー オペレーターを宣言し、実際の作業をその中のメンバー オペレーターに委譲することです。

template<typename T, typename U>
Vec3<T> operator* const Vec3<T>& lhs, const U& rhs )
{
    return lhs *= rhs;
}

これで、コンパイラはパラメーター間の型変換を実行し、それが不可能な場合はエラーを出力できるようになりました。

于 2013-06-25T07:24:45.583 に答える