I have this code:
template <class T>
class Something
{
T val;
public:
inline Something() : val() {}
inline Something(T v) : val(v) {}
inline T& get() const { return val; }
inline Something& operator =(const Something& a) { val = a.val; return *this; }
};
typedef Something<int> IntSomething;
typedef Something<const int> ConstIntSomething;
class Other
{
public:
IntSomething some_function()
{
return IntSomething(42);
}
ConstIntSomething some_function() const
{
return ConstIntSomething(42);
}
};
void wtf_func()
{
Other o;
ConstIntSomething s;
s = o.some_function();
}
However, the compiler picks the wrong overload of Other::some_function() in wtf_func() (i.e. the non-const one). How can I fix this? Note that for certain reasons I cannot change the name of Other::some_function().
ois not const-qualified, so the non-constsome_functionis selected. If you want to select the const-qualified overload, you need to add the const qualifier too:When overload resolution occurs, the compiler only looks at the
o.some_function()subexpression; it does not look at the context around the function call to decide to pick something else. Further, the return type of a member function is not considered during overload resolution.Note that it may make more sense for
IntSomethingto be implicitly convertible toConstIntSomething, either using anoperator ConstIntSomething()overload inIntSomething(less good) or using a non-explicitConstIntSomething(IntSomething const&)constructor inConstIntSomething(more good).