2011-07-31 13 views
2

私は以下に示すこれらの関数テンプレートを作成したかったのです。その目的はファンクタを比較することですが、boost.bind型のファンクタの特殊なケースをカバーする必要がありました。テンプレートのオーバーロード(引数の数の差)

template<typename R, typename F, typename L> 
void compare(boost::_bi::bind_t<R, F, L>& lhs, boost::_bi::bind_t<R, F, L>& rhs) 
{ 
    std::cout << lhs.compare(rhs) << std::endl; 
} 

template<typename T> 
void compare(T lhs, T rhs) 
{ 
    std::cout << (lhs == rhs) << std::endl; 
} 

問題は、私はcompare(boost::bind(func, 1), boost::bind(func, 1))を行う際に、コンパイラは2番目のテンプレートを使用しようとしていることです。私が2番目のものをコメントアウトすると、boost.bind型に特化したものが正しく使用され、すべて正常に動作します。

使用する正しい関数テンプレートを選択するにはどうすればよいですか?

+1

ブーストの実装のプライベートタイプに頼っているようです。あなたは、あなたが渡しているものに対して正確に正しいタイプを持っていると確信していますか?最初のテンプレートを使用するために必要な暗黙的な変換があれば、2番目のテンプレートは元の型でインスタンス化できるため、2番目のテンプレートが優先されます。 –

+0

私は最初に 'int i = boost :: bind(func、1)'を実行してコンパイラにバインドの戻り値を教えてもらうようにしました。さらに、[function_equal templates](http://www.boost.org/doc/libs/1_47_0/boost/bind/bind.hpp)も引数としてbind_tを取るので、私もそれを行うのが安全であるはずです。 –

+2

ちょうど 'boost :: bind'を検索し、値によってそのパラメータを返します。' compare(boost :: find(func、1)、boost :: bind(func、1)) 'は最初のテンプレートを一時参照を非const参照にバインドすることはできません。 'const'を最初に追加するとOKになります。より一般的なテンプレートをコメントアウトするとなぜ機能するかについては、私はあまりよく分かりません。私の実装では、一般的なテンプレートがインスタンス化されるときにエラーが発生します。 –

答えて

1

boost::bindは、const参照にバインドできない値を返します。あなたのより専門化されたテンプレートは、値によって引数を取るか、constで参照する必要があります。そうでない場合は、コールで考慮されません。compare(boost::bind(func, 1), boost::bind(func, 1))

このテストプログラムは、自分のプラットフォームで正しくコンパイルされて動作します。

#include <boost/bind/bind.hpp> 
#include <iostream> 
#include <ostream> 

template<typename R, typename F, typename L> 
void compare(const boost::_bi::bind_t<R, F, L>& lhs 
       , const boost::_bi::bind_t<R, F, L>& rhs) 
{ 
    std::cout << lhs.compare(rhs) << std::endl; 
} 

template<typename T> 
void compare(T lhs, T rhs) 
{ 
    std::cout << (lhs == rhs) << std::endl; 
} 

void func(int) {} 

int main() 
{ 
    compare(boost::bind(func, 1), boost::bind(func, 1)); 
} 
関連する問題