2017-10-04 1 views
2

を定義しているが、誰かが私を理解する助けてください、なぜ次のコードはコンパイルされません:ないキャストキャスト演算子は

template< typename T > 
class A 
{}; 

template< typename U > 
class wrapper 
{ 
    public: 
    // cast operator 
    operator wrapper< A<void> >() 
    { 
     return wrapper< A<void> >{}; 
    } 

}; 

template< typename T > 
void foo(wrapper< A<T> >) 
{} 


int main() 
{ 
    foo( wrapper<void>{}); 
} 

エラーメッセージ:

t.cpp:24:7: error: no matching function for call to 'foo' 
     foo( wrapper<void>{}); 
     ^~~ 
t.cpp:18:10: note: candidate template ignored: could not match 'A<type-parameter-0-0>' against 'void' 
    void foo(wrapper< A<T> >) 
     ^
1 error generated. 

とどのようにそれを修正するの?

wrapper<void>は、class wrapperのキャスト演算子を使用してwrapper< A<void >にキャストされると予想しました。スムーズにコンパイル

int main() 
{ 
    foo(static_cast< wrapper< A<void> > >(wrapper<void>{})); 
} 

を次のように

+1

明示的な静的キャストであるため、テンプレートパラメータの控除には正しいタイプが適用されます。可能性のあるユーザー定義のコンバージョンを考慮したテンプレートパラメータの控除を想定しているようです。 – VTT

答えて

3

暗黙のキャストのため、foo -sテンプレートの除外が失敗するという問題があります。型Tを推定する

  • foo試行
  • P = wrapper<void>、A = wrapper<A<T>>
  • fooA<T>だから

が何であるかを推測するために何の可能な方法を持っていない、我々はfooはTを推測支援する必要があり

解決策1

fooはTが明示的に何であるか知ってみましょう:

fooはTが何であるかを知っているように、明示的に wrapper< A<void> >wrapperキャスト
foo<void>(wrapper<void>{}); 

ソリューション2

:実行し、それを修正するには

foo(static_cast< wrapper< A<void> > >(wrapper<void>{})); 
+0

控除が失敗するのはなぜですか?テンプレートだけでなく、void foo(wrapper )でも動作しますか? – DrSvanHay

3

あなたが明示的でそれを修正することができますがstatic_castを使用してwrapper< A<void> >wrapper<void>をキャスト。


テンプレート控除が正確に変換を行うことなく、テンプレートパラメータを一致させようないことに注意してください。これは、物事を正確に一致させるためにキャストが必要な場合、キャストは明示的でなければならないことを意味します。