通用重载运算符

时间:2016-12-13 09:20:03

标签: c++ generics operator-overloading c++14 c++17

我喜欢使用auto和decltype,然后我想知道是否可以使用auto执行泛型运算符。实际上,因为c ++ 14 et可以做到这一点:

decltype(auto) add(auto v1, auto v2) {
  return v1 + v2;
}

但是,我想尝试使用包含如下值的模板化类:

template<typename T>
class test {
 public:
  T value;
  test(T val) {
    value = val;
  }
};

然后我需要一个重载运算符+就像这个工作:

template<typename T>
T operator+(test<T> const& t1, test<T> const& t2) {
    return t1.value + t2.value;
}

这已经非常棒了。但是,我想要一个泛型运算符+,可以由多个类使用。喜欢这些:

decltype(t1.value) operator+(auto const& t1, auto const& t2) {
    return t1.value + t2.value;
}

template<typename T>
T operator+(auto const& t1, auto const& t2) {
    return t1.value + t2.value;
}

,无法编译。

在C ++ 14/17中,有没有办法让泛型重载运算符,这些运算符可以被许多类使用,就像我写的那样?

PS:这里是你的测试代码,用gcc7快照编译但不用clang编译,似乎不允许auto in函数原型: link to compiler explorer code

#include <iostream>

template<typename T>
class test {
 public:
  T value;
  test(T val) {
    value = val;
  }
};

template<typename T>
T operator+(test<T> const& t1, test<T> const& t2) {
    return t1.value + t2.value;
}

decltype(auto) add(auto v1, auto v2) {
  return v1 + v2;
}

int main() {
  decltype(5) v1 = 5;
  decltype(v1) v2 = 3;
  test<decltype(v1)> t(v1);
  test<decltype(v2)> t2(v2);

  return add(t, t2);
}

1 个答案:

答案 0 :(得分:3)

如果我理解了您的问题,您可以使用尾随返回类型:

auto operator+(auto const& t1, auto const& t2) -> decltype(t1.value + t2.value) {
    return t1.value + t2.value;
}

对于不接受auto参数的编译器,您可以简单地回退到两个模板参数:

template <typename U, typename V>
auto operator+(U const& t1, V const& t2) -> decltype(t1.value + t2.value) {
    return t1.value + t2.value;
}

评论中提及@Jarod42,您可能希望使用decltype(t1.value + t2.value)代替decltype(t1.value)来正确处理转化和促销。