I am attempting to create a class that mimics a reference to some value. To do that I want to define operator overloads so that it behaves appropriately. When I do that, operator+
resolves correctly, but operator*
complains with error: use of overloaded operator '*' is ambiguous (with operand types 'ref<int>' and 'int')
(at least in Clang 3.4).
Here's what I've done (with most things made explicit and removing all of the extra stuff):
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;
}
Full output:
$ 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.
What am I missing?
Aucun commentaire:
Enregistrer un commentaire