参考类中的Amibiguous运算符?

时间:2015-06-29 19:12:40

标签: c++

我正在尝试创建一个模仿对某个值的引用的类。为此,我想定义运算符重载,以使其行为正常。当我这样做时,operator+会正确解析,但operator*会抱怨error: use of overloaded operator '*' is ambiguous (with operand types 'ref<int>' and 'int')(至少在Clang 3.4中)。

这就是我所做的事情(大多数事情都是明确的,并删除了所有额外的东西):

template <typename T> class ref {
private:
  T &val;

public:
  ref(T &r) : val(r) {}

  template <typename R> ref<T> &operator=(R const &rhs) {
    val = rhs;
    return *this;
  }

  // BINOP_TY(+);
  template <typename L, typename R>
  friend auto operator+(L lhs, ref<R> rhs) -> decltype((lhs) + (rhs.val));

  template <typename L, typename R>
  friend auto operator+(ref<L> lhs, R rhs) -> decltype((lhs.val) + (rhs));

  template <typename L, typename R>
  friend auto operator+(ref<L> lhs, ref<R> rhs)
      -> decltype((lhs.val) + (rhs.val));

  // BINOP_TY(*);
  template <typename L, typename R>
  friend auto operator*(L lhs, ref<R> rhs) -> decltype((lhs) * (rhs.val));

  template <typename L, typename R>
  friend auto operator*(ref<L> lhs, R rhs) -> decltype((lhs.val) * (rhs));

  template <typename L, typename R>
  friend auto operator*(ref<L> lhs, ref<R> rhs)
      -> decltype((lhs.val) * (rhs.val));
};

// BINOP(+);
template <typename L, typename R>
auto operator+(L lhs, ref<R> rhs) -> decltype((lhs) + (rhs.val)) {
  return lhs + rhs.val;
}

template <typename L, typename R>
auto operator+(ref<L> lhs, R rhs) -> decltype((lhs.val) + (rhs)) {
  return lhs.val + rhs;
}

template <typename L, typename R>
auto operator+(ref<L> lhs, ref<R> rhs) -> decltype((lhs.val) + (rhs.val)) {
  return lhs.val + rhs.val;
}

// BINOP(*);
template <typename L, typename R>
auto operator*(L lhs, ref<R> rhs) -> decltype((lhs) * (rhs.val)) {
  return lhs * rhs.val;
}

template <typename L, typename R>
auto operator*(ref<L> lhs, R rhs) -> decltype((lhs.val) * (rhs)) {
  return lhs.val * rhs;
}

template <typename L, typename R>
auto operator*(ref<L> lhs, ref<R> rhs) -> decltype((lhs.val) * (rhs.val)) {
  return lhs.val * rhs.val;
}

// Works.
void plus(ref<int> r, int i) {
  r = r + i;
}

// Fails.
void mult(ref<int> r, int i) {
  r = r * i;
}

完整输出:

$ clang++ -std=c++11 ref2.cpp
ref2.cpp:75:13: error: use of overloaded operator '*' is ambiguous (with operand types 'ref<int>' and 'int')
      r = r * i;
          ~ ^ ~
ref2.cpp:29:19: note: candidate function [with L = int, R = int]
      friend auto operator*(ref<L> lhs, R rhs) -> decltype((lhs.val) * (rhs));
                  ^
ref2.cpp:59:10: note: candidate function [with L = int, R = int]
    auto operator*(ref<L> lhs, R rhs) -> decltype((lhs.val) * (rhs)) {
         ^
1 error generated.

我错过了什么?

0 个答案:

没有答案