首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否有基于宏的适配器从类中生成函子?

是否有基于宏的适配器从类中生成函子?
EN

Stack Overflow用户
提问于 2013-08-11 18:35:23
回答 4查看 330关注 0票数 0

创建一个函子需要一个不必要的锅炉板。国家必须写四遍!

代码语言:javascript
复制
struct f{
  double s; // 1st
  f(double state): s(state) {} // 2nd, 3rd and 4th
  double operator() (double x) {
    return x*s;
  }
};

是否有一个只有double functor(state)(x){ return x*state; }或类似宏的库。

BOOST_FOREACH是一个工作良好的宏适配器。我在找类似的东西。

任何关于如何写一个人的建议,我们也很感激。

ps。使用struct对函子比绑定类的运算符()还是将函数绑定为函子?更快

更新(1)

关于兰巴达:

函子必须是模块化的,也就是说,它在其他功能中应该是可重用的。lambda必须在一个函数中-- lambda必须在main中被从main和main之外的其他函数调用,不能调用main中定义的lambda。

EN

回答 4

Stack Overflow用户

发布于 2013-08-11 20:48:39

依赖聚合初始化如何?只需不声明构造函数:

代码语言:javascript
复制
struct f {
    double s;
    double operator()(double x) {
        return x * s;
    }
};

像这样使用它

代码语言:javascript
复制
int main()
{       
    auto ff = f{42};
    std::cout << ff(2);
    return 0;
}
票数 4
EN

Stack Overflow用户

发布于 2013-08-11 19:02:49

将您想要的功能(例如乘法)定义为一个函数,然后使用std::bind()创建一个合适的函数对象:

代码语言:javascript
复制
#include <functional>

double some_operation(double state, double x) {
    return state * x;
}

int main() {
    auto function = std::bind(&some_operation, 17, std::placeholders::_1);
    return function(18);
}

由于通过函数指针进行的调用通常不能内联,因此您可能希望将函数作为函数对象来编写:

代码语言:javascript
复制
#include <functional>

struct some_operation {
    double operator()(double state, double x) const {
        return state * x;
    }
};

int main() {
    auto function = std::bind(some_operation(), 17, std::placeholders::_1);
    return function(18);
}

下面是一个测试程序,它似乎表明手工创建的函数对象和绑定函数对象的速度大致相同,也就是说,我得到的结果是

代码语言:javascript
复制
in 90 ms, functor as a struct; result = 1.5708e+16
in 262 ms, function pointer through bind; result = 1.5708e+16
in 261 ms, function through bind; result = 1.5708e+16
in 87 ms, function object through bind; result = 1.5708e+16
in 88 ms, non-called bind with function; result = 1.5708e+16
in 88 ms, non-called bind with function pointer; result = 1.5708e+16

使用嘎吱声的最新版本(更准确地说是:clang version 3.4 (trunk 182411))在MacOS系统上使用-O2选项进行优化。Using和gcc (更准确地说是:gcc version 4.9.0 20130811 (experimental) (GCC))给出了类似的结果。

函数对象是在本地上下文中构建的,还是通过模板参数传递给单独的函数,这似乎有很大的区别。这种差异是很有趣的,因为我预计bind()函数的大多数使用都会导致在某个地方假冒结果函数对象。

代码是基于https://stackoverflow.com/a/18175033/1120273

代码语言:javascript
复制
#include <iostream>
#include <functional>
#include <chrono>

using namespace std;
using namespace std::placeholders;
using namespace std::chrono;

struct fs {
    double s;
    fs(double state) : s(state) {}
    double operator()(double x) {
        return x*s;
    }
};

struct ff {
    double operator()(double x, double state) const {
        return x * state;
    }
};

double fb(double x, double state) {
    return x*state;
}

template <typename Function>
void measure(char const* what, Function function)
{
    const auto stp1 = high_resolution_clock::now();
    double sresult(0.0);
    for(double x=0.0; x< 1.0e8; ++x) {
        sresult += function(x);
    }
    const auto stp2 = high_resolution_clock::now();
    const auto sd = duration_cast<milliseconds>(stp2 - stp1);  
    cout << "in " << sd.count() << " ms, "; 
    cout << what << "; result = " << sresult << endl;
}


int main() {
  double state=3.1415926;

  measure("functor as a struct", fs(state));
  measure("function through bind", std::bind(&fb, _1, state));
  measure("function object through bind", std::bind(ff(), _1, state));


  {
      const auto stp1 = high_resolution_clock::now();
      double sresult(0.0);
      auto function = std::bind(fb, _1, state);
      for(double x=0.0; x< 1.0e8; ++x) {
          sresult += function(x);
      }
      const auto stp2 = high_resolution_clock::now();
      const auto sd = duration_cast<milliseconds>(stp2 - stp1);  
      cout << "in " << sd.count() << " ms, "; 
      cout << "embedded bind with function; result = " << sresult << endl;
  }
  {
      const auto stp1 = high_resolution_clock::now();
      double sresult(0.0);
      auto function = std::bind(&fb, _1, state);
      for(double x=0.0; x< 1.0e8; ++x) {
          sresult += function(x);
      }
      const auto stp2 = high_resolution_clock::now();
      const auto sd = duration_cast<milliseconds>(stp2 - stp1);  
      cout << "in " << sd.count() << " ms, "; 
      cout << "embedded bind with function pointer; result = " << sresult << endl;
  }    

  return 0;
}
票数 2
EN

Stack Overflow用户

发布于 2013-08-11 20:06:38

我们有兰巴达做这个:

代码语言:javascript
复制
double s = 42;
auto f = [s](double x) {
    return s * x;  
};

在第2行中,只提到一次状态(因为在实际表达式中,您似乎不算状态)。第1行的初始化是否值得商榷,您想要的表单不包含任何必要的初始化,因此我假设这是可以接受的。

在c++14中,我们将扩展lambda捕获语法,允许更简洁的形式:

代码语言:javascript
复制
auto f = [s{42}](double x) {
    return s * x;  
};
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18175309

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档