C++ 11:创建一个函数总是返回true,使用的函数参数

C++ 11:创建一个函数总是返回true,使用的函数参数

问题描述:

我想用下面的模板成员函数C++ 11:创建一个函数总是返回true,使用的函数参数

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; }); 

,但我想这个lambda函数可以改善没有?

不知道拉姆达如何能改善,但你可以定义给出任何输入总是返回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; 
    } 
}; 

这将被用来作为:

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

Live demo

+1

伟大的答案。只是挑剔(或者可能是风格问题):在C++ 11版本中,您可以创建'struct always_true_t',然后'const always_true_t always_true' – bolov

您可以创建一个lambda返回true,并设置它作为默认参数。

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参考这里工作。

虽然明确表示可能是更好的设计。只是一个选项,它 “短”

+0

多态lambda被添加到C++ 14中,问题被标记为C++ 11 。你无法使用右值引用的原因是你将'always_true'定义为左值。如果将默认模板参数设置为左值ref,则“Filter &&”将起作用,即“decltype(true_filter)&' –

C++ 14:

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>()); 

这有所涉及的lambda的真实性在类型系统中被编码的优点,这使编译器能够更轻松地优化其行为。

这也让你做always<std::false_type>always<std::integral_constant<int, 42>>()

在C++ 17我会做:(?也许always<nullptr>()

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

允许always<true>()always<42>()