【问题标题】:Generic overloading operator泛型重载运算符
【发布时间】:2017-04-28 07:04:42
【问题描述】:

我喜欢使用 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,这似乎不允许函数原型中的自动: 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);
}

【问题讨论】:

  • "确实,因为 c++14 et 可以做到这一点:" 不,你不能。 auto 只能用作 lambdas 中的参数占位符。将其扩展到常规功能的是 Concepts TS。而 C++14 不包括这一点。

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


【解决方案1】:

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

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;
}

正如 cmets 中提到的@Jarod42,您可能希望使用decltype(t1.value + t2.value) 而不是decltype(t1.value) 来正确处理转化和促销。

【讨论】:

  • gcc 不会接受 auto 作为普通函数的参数类型,如果你使用 -pedantic 编译。我建议在这种情况下它是非标准的。
  • @RichardHodges 你可能是对的(在实际看到这个问题之前我不知道这是可能的......),我提出了一个不使用 auto 作为参数类型的替代方案。
  • 我不知道为什么我没有尝试使用自动作为回报。
  • 顺便说一句,您可能希望decltype(t1.value + t2.value) 而不是decltype(t1.value) 来处理促销和其他可能的转换。
  • @Jarod42 是的,这可能会更好,但我只是遵循了 OP 的代码。将更新答案。
猜你喜欢
  • 1970-01-01
  • 2023-03-24
  • 2016-01-25
  • 2012-12-10
  • 2015-05-23
  • 1970-01-01
  • 2018-10-19
  • 1970-01-01
  • 2010-10-19
相关资源
最近更新 更多