我正在尝试创建一个模仿对某个值的引用的类。为此,我想定义运算符重载,以使其行为正常。当我这样做时,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.
我错过了什么?