【问题标题】:How to pass numeric operator as a parameter?如何将数字运算符作为参数传递?
【发布时间】:2021-01-08 03:19:52
【问题描述】:

在 C++ 中,我们可以执行以下操作,

template <class OP>
int f(OP op){
   return op(1,2);
}

int main(){
    int res1 = f(std::plus<int>{});
    int res2 = f(std::multiplies<int>{});
}

我怎么能用简单的数字运算符做同样的事情,

int main(){
    int res1 = f(+);
    int res2 = f(*);
}

没错,我想知道的是函数f中'return'这行怎么写。

【问题讨论】:

  • #define f(op) []{ return 1 op 2; }()
  • 操作符并不多,因此为每个操作符定义一个包装器实际上是最少的代码,如果这真的让您感到困扰,您可能可以单行定义。最好将其保持打开状态,例如使用 std::function 或 lambda,因为这样您就可以进行非平凡的操作,例如乘加。
  • 你不能。对于类或枚举类型,非成员运算符是可行的,因此可指定为参数,但不适用于算术本机类型。您似乎在询问如何将T operator +(T,T) 作为参数传递,简而言之,您不能(如果您可以std::plus 会有什么好处?
  • @tadman • 我认为如果你想做 OCaml,就使用 OCaml,而不是 C++ 试图伪装成 OCaml。
  • @Eljay 我的意思是更多关于#define 这是一种肮脏的行为。

标签: c++ parameters operator-keyword


【解决方案1】:

我怎么能用简单的数字运算符做同样的事情,

你不能;不使用函数模板。运算符不是可以作为参数传递或存储在对象中的东西。

我想知道的是函数f中'return'这行怎么写。

您无法将f 写成一个函数模板来使f(+) 工作,因为f(+) 的语法格式不正确。

comment 所示,可以使用宏来完成:

#define MY_MACRO_WITH_UNIQUE_NAME(op) \
[]{                                   \
    return 1 op 2;                    \
}()

int res1 = MY_MACRO_WITH_UNIQUE_NAME(+);
int res2 = MY_MACRO_WITH_UNIQUE_NAME(*);

#undef MY_MACRO_WITH_UNIQUE_NAME

请注意,宏容易发生名称冲突,因此请确保您选择的名称未被使用,也不太可能被其他人使用。

没有理由这样做,而只是使用您最初编写的模板和std::plus。例如,宏对于定义一组相同的运算符重载很有用,因为在这种情况下,您无法避免使用运算符符号。这是我写的东西:

#define FOO_DEFINE_OP(op, trait)                                     \
    template <class T, class = std::enable_if_t<trait<T>::value> >   \
    constexpr bool operator op(const foo<T>& lhs, const foo<T>& rhs) \
    {                                                                \
        return lhs.t op rhs.t;                                       \
    }

FOO_DEFINE_OP(==, boost::has_equal_to)
FOO_DEFINE_OP(!=, boost::has_not_equal_to)
FOO_DEFINE_OP(<,  boost::has_less)
FOO_DEFINE_OP(<=, boost::has_less_equal)
FOO_DEFINE_OP(>,  boost::has_greater)
FOO_DEFINE_OP(>=, boost::has_greater_equal)

#undef FOO_DEFINE_OP

随着在 C++20 中引入默认比较运算符,这有望减少。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-18
    • 2018-03-27
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 2013-06-23
    相关资源
    最近更新 更多