2011-02-09 20 views
1

次の例を検討してください。 G ++ 4.3.0を使用して、これをコンパイルするテンプレート関数参照の失敗

#include <iostream> 
#include <boost/optional.hpp> 

template < typename A > 
int boo(const boost::optional<A> &a); 

template < typename A > 
int foo(const A &a) 
{ 
    return boo(a); 
} 

template < typename A > 
int boo(const boost::optional<A> &) 
{ 
    return 3; 
} 


int main() 
{ 
    std::cout << "foo = " << foo(3) << std::endl; 
    std::cout << "boo = " << boo(3) << std::endl; 
} 

は、次のコンパイルエラーがスローされます。

dfg.cpp: In function ‘int main()’: 
dfg.cpp:25: error: no matching function for call to ‘boo(int)’ 
dfg.cpp: In function ‘int foo(const A&) [with A = int]’: 
dfg.cpp:24: instantiated from here 
dfg.cpp:12: error: no matching function for call to ‘boo(const int&)’ 

は、私は(C++の標準からの参照を持つ可能な場合)違った何をすべきでしょうか? なぜそれが起こっているのですか、どうすれば修正できますか?

EDIT

修正はfooで正しい型を作成することです:

template < typename A > 
int foo(const A &a) 
{ 
    const boost::optional<A> optA(a); 
    return boo(optA); 
} 

しかし、質問はまだ立っている:それは自動的に作成されていない理由?ここで

答えて

5
return boo(a); 

aのタイプはintで、タイプintの引数を受け入れ名前boo持つ機能はありません。したがって、あなたは、このエラーを参照してください。int暗黙的boost::optional<int>に変換することができ

dfg.cpp:25: error: no matching function for call to ‘boo(int)’

場合でも、コンパイラは呼び出し元のサイトからboost::optional<T>ためのテンプレート引数を推測することはできません。これは、非推測コンテキストの一つだどこに明示的としてタイプを言及する必要性、標準$ 14.8.2.1で述べている

return boo<A>(a); 

if a template-parameter is not used in any of the function parameters of a function template, or is used only in a non-deduced context, its corresponding template-argument cannot be deduced from a function call and the template-argument must be explicitly specified.

+0

などのオプションを取るものとブーイングの独自のテンプレートを作成しますが、後押し::オプション< int >を作成する必要がある、ないだろうか? –

+0

@VJo:私は自分の答えを編集しました。それをもう一度見てください。 – Nawaz

2

この問題を解決するには、明示的にする必要がありbooを呼び出すとき、すなわち

return boo<A>(a); 

、タイプを指定します
std::cout << "boo = " << boo<int>(3) << std::endl; 

EDIT:あなたはoptional<int>がintから暗黙のコンストラクタを持っているので、コンパイラはそれはあなたがしようとしているタイプである知っておくべきことを想定している

1

を、私の説明を取り出し、それはゴミだった、ナワズの説明が良い..です作成します。

テンプレートタイプの控除はそれには適用されません。

あなたははい一般化

template< typename A > int boo(const A& a); 
template < typename A > 
int boo(const boost::optional<A> &) 
{ 
    return 3; 
} 

template < typename A > 
int boo(const A & a) 
{ 
    return boo<A>(boost::optional(a)); // allows implicit conversion 
} 
関連する問題