2016-11-16 12 views
3

に使用する場合はtrueを返す関数を作成する最も簡単な方法は、私はクライアントからこの関数を呼び出すための最良の方法ですC++ 11:常に関数の引数

template <typename Entity> 
class SomeCollection 
{ 
    // .... 

    template <typename Measure, typename Filter> 
    Entity maximalEntity(Measure&& measure, Filter&& requirement) 
    { 
     auto maxEntity = Entity(); 
     auto maxValue = -std::numeric_limits<double>::infinity(); 

     for (auto ent /* some iteration method*/) 
     { 
      auto measurement = measure(ent); 
      if (requirement(ent) && measurement > maxValue) 
       std::tie(maxEntity, maxValue) = std::make_tuple { ent, measurement }; 
     } 
     return maxEntity; 
    } 

    // ... 
}; 

何次のテンプレートメンバ関数を使用したいですフィルタ要件なしのコード(最大要素を持つため)?

私が思い付くことができる最高は次のとおりです。

class Something; 
double measure(Something&); 
SomeCollection<Something> collection; 

auto maximum = collection.maximalEntity(measure, [](const Something&) { return true; }); 

しかし、私は、このラムダ関数が無い改善することができると思いますか?

答えて

8

ラムダはを向上させることができますが、あなたはどのような入力は、常にtrueを返します与えられた(また、ここで使用することができた)一般的なラムダを定義できるかわからない:

auto always_true = [](auto&&...) { return true; }; 

を、あなたが使用しますそれのように:

auto maximum = collection.maximalEntity(measure, always_true); 

Live demo


C++ 11の等価な実装は以下の通りです:

のように使用される
struct always_true { 
    template<typename... Args> 
    bool operator()(Args&&...) const noexcept { 
     return true; 
    } 
}; 

:あなたはtrueを返すラムダとセットを作成することができ

auto maximum = collection.maximalEntity(measure, always_true{}); 

Live demo

+1

すばらしい答えです。ちょうどニックピッキング(または多分スタイルの問題):C++ 11のバージョンでは 'struct always_true_t'を作成してから' const always_true_t always_true'を作成することができます – bolov

2

デフォルトのパラメータとして使用します。

auto true_filter = [](const Something& arg){ return true; }; 
//auto true_filter = [](auto&& arg){ return true; }; if you have c++14 
... 

template <typename Measure, typename Filter = decltype(true_filter)> 
Entity maximalEntity(Measure&& measure, Filter requirement = true_filter) 
{ 

... 
auto maximum = collection.maximalEntity(measure); 

FilterFilter&&から変更されています。私はrvalue refsで動作するようにはなっていません。

明示的に述べた方がデザインが優れている可能性があります。

template<class T> 
auto always() { 
    return [](auto&&...)->T{return {};}; 
}; 

またはC++ 11で:

template<class T> 
struct always { 
    template<class...Args> 
    T operator()(Args&&...)const{ return {}; } 
}; 

使用:

collection.maximalEntity(measure, always<std::true_type>()); 

これは持っている

+0

多態性ラムダはC++ 14で追加されました。 。右辺値refで動作させることができなかった理由は、左辺値として 'always_true'を定義したからです。デフォルトのテンプレート引数をlvalue refにすると 'Filter && 'が動作します。つまり、' decltype(true_filter)& ' –

1

C++ 14の "短い" それを持っているだけでオプション関与するラムダの真実が型システムでコード化されるという利点は、コンパイラがその動作を最適化することを少し容易にする。 (?多分always<nullptr>()

always<true>()always<42>()を許可
template<auto x> 
auto always() { 
    return [](auto&&)->std::integral_constant<decltype(x), x> 
    { return {}; }; 
} 

また、これはあなたが私がしたいC++ 17では

などalways<std::false_type>またはalways<std::integral_constant<int, 42>>()を行うことができます。

関連する問題