【问题标题】:Parameter to use std::greater or std::less as argument使用 std::greater 或 std::less 作为参数的参数
【发布时间】:2014-03-28 01:17:14
【问题描述】:

我想创建一个函数,其参数接受std::greater<int>std::less<int> 作为参数。不过,我坚持使用参数的语法。

这是我尝试过的格式:

myFunction(int a, int b, bool *comp(int, int)) { … }
…
std::greater<int> bigger;
myFunction(2, 3, bigger);

但这不起作用,我怀疑第三个参数完全错误。它实际上应该是什么?

无法将std::greater&lt;int&gt; 转换为bool* (*)(int, int)

【问题讨论】:

  • 改为传递std::greater&lt;int&gt;()
  • 谢谢。我已经更新了我的问题以传递更大的实例而不是类。错误是一样的;我只是第一次没有仔细复制我的代码。我的错。
  • 顺便说一句,您的参数是一个函数(在该上下文中转换为函数指针)接受两个ints 并返回一个bool *

标签: c++ c++11 functor comparison-operators


【解决方案1】:

采用比较器的函数通常通过模板实现:

template <typename Comparator>
myFunction(int a, int b, Comparator comp) { … }

但您也可以使用std::function 来实现它:

myFunction(int a, int b, std::function<bool (int, int)> ) { … }

第一个版本在标头中公开代码,但通常性能更好。 至于第二个版本,可以将实现隐藏在.cpp文件中, 但是由于无法内联,您会失去一些性能 比较器调用。

【讨论】:

    【解决方案2】:

    所以这里的诀窍是std::lessstd::greater 实际上是可以简单构造的无状态函数对象。但它们不支持转换为函数指针。

    有效的选择是(A)通过template 参数获取比较器并在标头中实现代码:

    template<typename C> void myFunc( int a, int b, C comp )
    

    这意味着您必须在头文件中实现它,或者 (B) 通过 std::function&lt; bool(int, int) &gt; 键入擦除函数对象:

    void myFunc( int a, int b, std::function< bool(int, int) > comp )
    

    这有一些成本(可能很重要?配置文件!)(通过针对无状态 std less/greater 的小对象优化来避免堆分配,但无论如何它往往会花费 virtual 函数调用,这也可能阻止内联)。

    或者 (C) 编写一些代码,让您获取无状态函子并将其转换为函数指针:

    template<typename T>
    using Type = T;
    template<typename StatelessFunctor>
    struct function_ptr_of_stateless_t {
      template<typename R, typename... Args>
      operator Type<R(Args...)>*() const {
        return [](Args... args)->R {
         return StatelessFunctor()(std::forward<Args>(args)...);
        };
      }
    };
    template<typename StatelessFunctor>
    function_ptr_of_stateless_t<StatelessFunctor> as_function_ptr() {
      return {};
    }
    
    bool myFunction( int a, int b, bool(*comp)(int, int) ) { return comp(a,b); }
    int main() {
      std::cout << myFunction(3,7, as_function_ptr<std::less<int>>() ) << "\n";
    }
    

    template 函数 as_function_ptr 采用无状态函子的类型并创建一个丢弃类型,让您可以将其强制转换为任何兼容的函数指针类型。

    这比std::function 解决方案的开销要小一些,因为对函数指针的调用往往比对virtual 方法的调用要快,此外,一些编译器(如gcc)在内联函数指针方面相当不错,甚至从一个编译单元到另一个编译单元。

    作为奖励,在 C++14 中,您可以使用:

    int main() {
      std::cout << myFunction(3,7, as_function_ptr<std::less<>>() ) << "\n";
    }
    

    而且它仍然工作得非常好。

    【讨论】:

      【解决方案3】:

      使用模板:

      template<class Callable>
      myFunction(int a, int b, Callable f);
      

      【讨论】:

      • 最简单的方法。为了清楚起见,我将其称为 Comparer 而不是 Callable
      猜你喜欢
      • 2013-01-27
      • 2018-09-21
      • 1970-01-01
      • 2012-10-10
      • 2021-04-25
      • 2021-01-07
      • 1970-01-01
      • 2019-02-11
      • 1970-01-01
      相关资源
      最近更新 更多