2017-05-31 14 views
1

ここでこのコードがコンパイルされない理由はよくわかりません。テンプレート間の暗黙の変換

dist(GenericVec2<T>,GenericVec3<T>) 

(これはかもしれしかし恐ろしい): そうのようなdistの()を呼び出すことが可能であるべきです。 GenericVec3引数は、変換演算子によって暗黙的にGenericVec2に変換されます。 私はここ

C++ implicit type conversion with template

この質問を見つけたが、それは(「friend」機能しなかったために変換演算子を設定する)私の問題に適用できるのであれば、私はとてもよく分かりません。 VSは、次のエラーが出力されます。ここでは

error C2672: 'dist': no matching overloaded function found 
error C2784: 'F dist(const GenericVec2<F> &,const GenericVec2<F> &)': could not deduce template argument for 'const GenericVec2<F> &' from 'Vec3' 
note: see declaration of 'dist' 

は私のコードは次のとおりです。事前に

#include <iostream> 

template<typename F> struct GenericVec2 
{ 
    GenericVec2<F>::GenericVec2(F _x = 0, F _y = 0) : x(_x), y(_y) {} 

    F x; 
    F y; 
}; 
using Vec2 = GenericVec2<float>; 

template<typename F> struct GenericVec3 
{ 
    GenericVec3<F>::GenericVec3(F _x = 0, F _y = 0, F _z = 0) : x(_x), y(_y), z(_z) {} 

    operator GenericVec2<F>()    { return *reinterpret_cast<GenericVec2<F>*>(&x); } 
    operator const GenericVec2<F>() const { return *reinterpret_cast<const GenericVec2<F>*>(&x); } 

    F x; 
    F y; 
    F z; 
}; 
using Vec3 = GenericVec3<float>; 

template<typename F> F dist(const GenericVec2<F>& a, const GenericVec2<F>& b) 
{ 
    return std::hypot(a.x - b.x, a.y - b.y); 
} 

int main() 
{ 
    Vec2 a{ 2.0f, 3.0f }; 
    Vec3 b{ 1.0f, 1.0f, 1.0f }; 
    Vec2 c = b; 

    float d = dist(a, Vec2{ b }); // works 
    float e = dist(a, b);   // doesn't compile 

    std::cin.ignore(); 

    return 0; 
} 

ありがとう!暗黙的な変換を

-Thomas

+2

あなた 'reinterpret_cast'もUBで厳格なエイリアシングとに割り当てられた最後のもの以外の' union'メンバーからの読み取りを中断します。そのコードを投げ捨ててゼロから始めれば、修復を超えて壊れてしまいます。なぜ私がこれを言っているのかわからない場合は、良い本を読む時です。 –

+0

私はできません、それは私のコードではなく、簡単には交換されません。私はそれをコンパイルする方法を知る必要があります(理想的には 'dist(a、Vec2 {b})'変換を行わないことが理想です) –

+0

実際の問題の一部ではないので、 –

答えて

0

問題が

template<typename F> F dist(const GenericVec2<F>& a, const GenericVec2<F>& b) 

にあなたがGenericVec2<float>から2番目のパラメータを推測することができない、ということであるあなたのGenericVec2クラスで次のコンストラクタを定義する必要があります。 一つの解決策は、friendに機能非テンプレート感謝をすることです:

template<typename F> struct GenericVec2 
{ 
    GenericVec2<F>::GenericVec2(F _x = 0, F _y = 0) : x(_x), y(_y) {} 


    friend F dist(const GenericVec2& a, const GenericVec2& b) 
    { 
     return std::hypot(a.x - b.x, a.y - b.y); 
    } 

    F x; 
    F y; 
}; 
+0

これはうまくいった! 'friend'キーワードを見てみると、私は推測する... –

0

ターゲットクラスがパラメータとしてソース・タイプ(またはソース・タイプからコンバーチブル型)を受け取るコンストラクタを持たなければならないことが可能。 GenericVec3に定義されているキャスト演算子は、明示的キャスト演算で使用されます。

だから、

GenericVec2(const GenericVec3<F>& v3) { ... }

+0

ここには何も変わりません。前と同じエラーです。現在のコード:https://pastebin.com/yzTECFHn –