Reputation: 569
#include <string>
using String = std::string;
class Base {
protected:
String value;
};
class Readonly : virtual Base {
public:
const String& method() const {
return value;
}
String& method() {
return value;
}
};
class Writeonly : virtual Base {
public:
Writeonly& method(const String& value) {
this->value = value;
return *this;
}
Writeonly& method(String&& value) {
this->value = std::move(value);
return *this;
}
};
class Unrestricted : public Readonly, public Writeonly {};
void usage() {
String string;
Unrestricted unrestricted;
unrestricted.method(string); // ambiguous
string = unrestricted.method(); // ambiguous
}
Can anyone explain to me why these method calls are ambiguous?
They are not ambiguous when put together in either "Writeonly" or "Readonly".
I'd like to use this for template based accessor properties. Therefore I want to be able to use instances of "Writeonly", "Readonly" and "Unrestricted".
Upvotes: 4
Views: 117
Reputation: 831
Probably you think it works because you are thinking in function overloading. The problem is that the different functions are in different scopes. In this case, the compiler does not have a list of overloaded functions to choose the correct one.
if you want it to work, you have to put the functions togheter in the same scope.
Upvotes: 0
Reputation: 69892
Because the compiler has found the name in two different scopes.
The trick is to bring both names into the scope of Unrestricted
:
class Unrestricted : public Readonly, public Writeonly {
public:
using Readonly::method;
using Writeonly::method;
};
Upvotes: 6