2012-04-09 8 views
4

がSTDに、一般的な等価物である:: equal_toブーストで任意の関数オブジェクトあり関数オブジェクトのなど家族をオブジェクト?ジェネリック同等ではstd ::大きい、

基本的に、のstd :: equal_toは

struct generic_equal_to 
{ 
    template <class T, class U> 
    bool operator()(const T& t, const U& u) const 
    { 
     return t == u; 
    } 
}; 

のようなものになるはずdecltypeができますが、私は(戻り値の型に起因する問題のためにトリッキーかもしれませんどのようにジェネリックのstd ::バージョンプラスなど見ることができますそれを解決する)。私は、なぜstd :: equal_to関数オブジェクト自体がテンプレート引数を必要とする必要があるのか​​考えられません。きっとどこかにブーストまたはこれらのバージョンが存在するSTLで

?もちろん書くことは簡単ですが、私は非常にライブラリコードの複製を嫌っています。特にこのようなことは明らかではありません。

EDIT:私は以下のようなものを、一般的なboost::fusion配列比較関数を書いていた

:私は代わりに、ラムダを使用しての、これをしたい、または別の関数オブジェクトの生成方法です理由として、いくつかのコンテキストとして

template <class T> 
bool sequence_equal(const T& left, const T& right) 
{ 
    return fusion::all(
     fusion::zip(left, right), 
     fusion::fused<generic_equal_to>()); 
} 

注意あなたが実質的に指定することはできませんISSEにつながるfusion::fused<generic_equal_to>一部、boost::lambdaまたはboost::phoenixタイプごとの機能オブジェクト。私は一つの解決策は、decltypeかもしれない推測:

fusion::fused<decltype(_1 == _2)>() 

けれども非常に厄介なようだ、とさえboost::lambdaまたはboost::phoenixがどのように実装されるかに応じて、動作しないことがあります - 私は本当にわかりません。

私はあなたがこの全体の問題を回避するためにfusion::make_fusedを使用することができます知っているが、その後は関数オブジェクトをインスタンス化する必要があります。私が考えた解決策は、その後、非テンプレートequal_to構造体だろう - 私は私generic_equal_toと呼ばれます。

私はそれが非常に些細な問題だと知っています。結局のところ、make_fused(_1 == _2)はおそらくfused<generic_equal_to>と同じアセンブリにインラインでダウンします。私はちょうどので、どこにでもSTL、ブーストまたはにはgeneric_equal_to関数オブジェクト、この質問がなかったことを信じることができませんでした。

+2

私はあなたが '演算子()(のconst T&T、のconst U&U)' –

+1

1を意味すると思うが、私はあなたがサポートされています1を見つけるとは思いません。この問題は重要です(私は昨日このコードを[回答](http://stackoverflow.com/questions/10063037/unordered-set-storing-elements-as-pointers/10063081#10063081)に書いていますが、それはBoostの開発者を引き付けるほどセクシーではなく、 'std :: equal_to'は標準化委員会がそれを廃止するのに十分なほど壊れていません。 – Potatoswatter

+0

@ AndrewTomazos-Fathomling hah yep!コンピュータを使わずにコードを書いて、構文をチェックしようとしています*常に*どこかで私を動かす – Ayjay

答えて

1

あなたが求めているものはまったく直接だとは思えませんが、ユースケースをカバーするだけでなく、それを超えるユーティリティもあります。彼らはBoost.LambdaBoost.Phoenix(後者はラムダライブラリーへのより一般的な後継者である)です。フェニックスで、

#include <boost/lambda/lambda.hpp> 
#include <iomanip> 
#include <iostream> 

struct foo {}; 

bool operator==(foo, foo) { return true; } 
bool operator==(foo, int) { return false; } 

template <typename T, typename U, typename Func> 
void f(const T& x, const U& y, Func func) 
{ 
    std::cout << func(x, y) << std::endl; 
} 

int main() 
{ 
    using namespace boost::lambda; // for placeholders 
    std::cout << std::boolalpha; 

    foo a, b; 
    int i = 0; 

    f(a, b, _1 == _2); 
    f(a, i, _1 == _2); 
} 

と同じ:

#include <boost/phoenix.hpp> 
#include <iomanip> 
#include <iostream> 

struct foo {}; 

bool operator==(foo, foo) { return true; } 
bool operator==(foo, int) { return false; } 

template <typename T, typename U, typename Func> 
void f(const T& x, const U& y, Func func) 
{ 
    std::cout << func(x, y) << std::endl; 
} 

int main() 
{ 
    using namespace boost::phoenix::arg_names; // for placeholders 
    std::cout << std::boolalpha; 

    foo a, b; 
    int i = 0; 

    f(a, b, arg1 == arg2); 
    f(a, i, arg1 == arg2); 
} 

これらのそれぞれは、(明らかな方法で他の演算子をサポートするように拡張することができ、一般的な平等のためBoost.Lambdaを使用して

例より一般的には、他の表現に変換する)。私は個人的にフェニックスに行くでしょう。ラムダが提供する機能よりも多くの機能が必要であることがわかったら、両方を含むことになるわけではありません。

+0

私は関数オブジェクトを生成する他の方法を知っていますが、私の質問の全体的なポイントは、 。それらはありますが、 'operator()'ではなく 'struct'ですべてテンプレート化されています。 – Ayjay

+0

'boost :: lambda'や' boost :: phoenix'を使用したくない理由をいくつか追加しました。 – Ayjay

+0

@Ayjay: 'make_fused'を使うだけです。彼らはすでにstdlibの機能を手動で実装することはありません。 – GManNickG

0

今C++ 14にstd::equal_to<void>がある(つまりもstd::equal_to<>として使用することができる)

std::equal_to<>を推定パラメータと戻り型を持つstd::equal_toの特殊化です。

template< class T, class U> 
constexpr auto operator()(T&& lhs, U&& rhs) const 
    -> decltype(std::forward<T>(lhs) == std::forward<U>(rhs)); 

LHSとRHSとの等価比較の結果を返します。

Docs

関連する問題