有没有办法概括只有操作不同的函数?

时间:2012-12-07 06:24:53

标签: c++

例如,假设我们有两个函数:

void sum(int x, int y)
{
   return x+y;
}

void minus(int x, int y)
{
   return x-y;
}

有没有办法让一个函数做一个总和或减去(或其他各种事情)取决于你想要使用哪个(可能是某种关键字),而不必明确地编写单独的函数?

5 个答案:

答案 0 :(得分:3)

有一种方式用这个问题下面的评论打败了我,但是你走了!

#include <functional>
#include <iostream>
#include <unordered_map>

std::unordered_map<std::string, std::function<int(int,int)>> operations =
{
  { "plus",   std::plus<int>()  },
  { "minus",  std::minus<int>() }
  // etc etc
};

int main(int argc, char** argv)
{
  std::cout << operations["plus"](1, 2) << std::endl;
  std::cout << operations["minus"](2, 1) << std::endl;

}

答案 1 :(得分:2)

我认为该函数实际上比您发布的函数更强大(它不编译从返回void的函数返回值)。您可以使用函数对象来自定义行为,例如:

#include <functional>
#include <iostream>
using namespace std::placeholders;

template <typename Op>
int operation(int a0, int a1, Op op = Op())
{
    return op(a0, a1);
}

int my_f0(int a0, int a2)
{
    return 2 * a0 + 3 * a2;
}

int my_f2(int a0, int a2, int f0, int f1)
{
    return f0 * a0 + f1 * a2;
}

int main()
{
    std::cout << operation<std::plus<int> >(2, 3) << "\n";
    std::cout << operation<std::minus<int> >(2, 3) << "\n";
    std::cout << operation(2, 3, std::multiplies<int>()) << "\n";
    std::cout << operation(2, 3, my_f0) << "\n";
    std::cout << operation(2, 3, std::bind(&my_f2, _1, _2, 2, 3)) << "\n";
}

自定义功能为operation()。其他代码只是为了展示如何定制。标准库算法在整个地方使用这种方法。

答案 2 :(得分:1)

您是不是想要编写单独的功能,还是想要从呼叫站点调用一个东西?如果你不介意多写一点,你可以使用操作符对象:

class Add {
  public:
  int operator(int a, int b) {
    return a+b:
  }
};

class Mul {
  public:
  int operator(int a, int b) {
    return a*b:
  }
};

template <class Op>
int doMyStuff(Op op, int a, int b) {
  return op(a,b);
}

// and you can call it like this:
doMyStuff(Add(),2,4);

当您实现某些不依赖于特定运算符但仅依赖于运算符的某些属性的转换时,此模式特别有用。例如,你可以实现一个数组求和器,它或者对数组的所有元素求和,或者计算数组中所有元素的乘积:循环保持不变,它只是改变的运算符。

template <class Op>
int summator(Op op, int* arr, int size) {
  int v = arr[0];
  for (int i=1; i<size; ++i) {
    v = op(v,arr[i]);
  }
  return v;
}

...

summator(Add(),myarray,10); //sum all elements
summator(Mul(),myarray,10); //product of all elements

答案 3 :(得分:0)

如果你不相信宏是邪恶的地狱,你可以这样做:

#define DEFINE_OPERATION(maName, maOp) \
  inline int maName (int a, int b) { return a maOp b; }

DEFINE_OPERATION(add, +)
DEFINE_OPERATION(sub, -)

#undef DEFINE_OPERATION

甚至:

#include <boost/preprocessor.hpp>

#define OPERATIONS ((add, +))((sub, -))

#define DEFINE_OPERATION(maR, maData, maElem) \
  inline int BOOST_PP_TUPLE_ELEM(2, 0, maElem) (int a, int b) { return a BOOST_PP_TUPLE_ELEM(2, 1, maEleme) b; }

BOOST_PP_SEQ_FOR_EACH(OPERATIONS, unused_, DEFINE_OPERATION)

#undef DEFINE_OPERATION

答案 4 :(得分:0)

#include <iostream>
#include <functional>
using namespace std;

template<template<class> class OP, class T> 
T do_op(T a, T b) {
    return  OP<T>()(a,b);
}

int main () {
    cout << do_op<plus>       (3,2) << endl;
    cout << do_op<minus>      (3,2) << endl;
    cout << do_op<multiplies> (3,2) << endl;
    cout << do_op<divides>    (3,2) << endl;
}