2012-03-30 21 views
4

を禁止する私は、次のしているデモコード:自動型推論

In function ‘int main()’:             
11:23: error: call of overloaded ‘func(int)’ is ambiguous 
11:23: note: candidates are: 
2:3: note: T func(const U&) [with int i = 1, T = int, U = int] 
5:3: note: T func(const T&) [with int i = 1, T = int] 

:それは役に立たないようだが、問題を表示するには十分ですので、私の実際のコードの煮詰めたバージョンである

template <int i, typename T, typename U> 
T func(const U &t){return i * t;} 

template <int i, typename T> 
T func(const T &t){return 2 * i * t;} 

int main() 
{ 
     return func<1, int>(1); 
} 

したがって、(テンプレートパラメータUの)自動型推論は、テンプレート関数の適切なバージョン(それは2パラメタのみを持つもの)を選択することに干渉することは明らかです。

私は両方のバージョンが基本的で特殊なテンプレートを持っている必要があります。

質問:この時点でタイプを自動的に推論しないようにコンパイラに指示する可能性はありますか(何らかの理由で:2つのパラメータしかないテンプレートを取るなど)。

+2

明白な他にも意味がありますか? (これは関数テンプレートに異なる名前を与えることです - あなたが何を使うべきかをコンパイラに指示するためにあなた自身で何かをする必要があるなら、同じ名前を持つのは何ですか?) – Mat

+0

これは最後の選択ですが、機能は同じ名前を共有する。 – Nobody

+0

名前を変更して再設計を提案します。私にとってこれは非常に悪いコードのような感じです。過負荷のセットのどの機能が使用されているのかという疑問で、人々はすでに簡単に混乱します。このようなものが存在すると、それはさらに困難になり、後で維持不能なコードにつながる可能性があります。 – LiKao

答えて

1

あなたが効果的に控除を無効にします(ただし、intのこのケースで同じ効果を持っているパラメータのリスト初期化原因となる)初期化子リスト、渡すことができます。

template <int i, typename T, typename U> 
T func(const U &t){return i * t;} 

template <int i, typename T> 
T func(const T &t){return 2 * i * t;} 

int main() 
{ 
     return func<1, int>({1}); 
} 

しかし、あなたの場合には、あなたの場合をfunc<N>(...)に電話したい場合は、func<N, T>(...)に電話する場合は、常にfunc<N, T, U>(...)に電話してほしいので、最初に電話をしたいので、にいつもの控除を無効にしてくださいUにパラメータを非引き継ぎ文脈にすることによって

template <int i, typename T, typename U> 
T func(typename std::common_type<const U &t>::type t){return i * t;} 

template <int i, typename T> 
T func(const T &t){return 2 * i * t;} 

int main() 
{ 
     return func<1, int>({1}); 
} 
+0

これは私が求めていたものだと思います。私はこの問題を迂回しましたが、私はこれが問題にはるかに適していると思います。 – Nobody

4

あなたは型推論を無効にすることはできませんが、オーバーロードの1を阻害するSFINAEを使用することができます。基本的に推論された型のUがタイプTであれば置換が失敗したためにテンプレート関数を作成

template <int N, typename T, typename U> 
typename std::enable_if< !std::is_same<T,U>::value, T >::type 
func(const U & t) { 
    return i*t; 
} 

を、その時点でSFINAEは潜在的な候補者のセットからテンプレートを削除し、他のテンプレートが選択されます。

C++ 11対応のコンパイラをお持ちでない場合は、enable_ifis_sameのテンプレートは簡単に書き込むことができます...それらのためのGoogleまたはコメントをドロップするだけです。

+0

これは私の問題を解決するかもしれませんが、質問に答えません。多分あなたはこれに対する答えを持っているでしょうか? – Nobody

+1

型推論は言語の一部であり、あなたはそれを単に無効にすることはできません。場合によっては(上記のように)*過負荷を無効にして、状況によっては考慮されないようにすることもできます。 –

+0

おそらく私は別の表現を使用していたはずです。私は、自動型推論を意味するのではなく、テンプレートパラメータが自動的に設定されるという事実です。だから、基本的に私はコンパイラに伝える構文を求めていました。 – Nobody