Consider this program:
template<typename T>
struct Foo
{
void foo(const T&) {}
void foo(T&) {}
};
int main()
{
Foo<double&> f;
double d = 3.14;
f.foo(d); //complains that foo() is ambigous
}
In the above, if Foo is instantiated as Foo<double>
, then things are fine, but if it is instantiated as Foo<double&>
, then the call to foo
becomes ambiguous. Is ref collapsing at play here when deducing the param types for foo
and if so why is constness being ignored?
Lets see what happens if we try to instatiate the Foo
class template:
template<typename T>
struct Foo {
void foo(T const&) {}
void foo(T&) {}
};
with template parameter double&
. Substituting T with double&
and according to reference collapsing rules you would get:
struct Foo {
void foo(double& const) {}
void foo(double&) {}
};
Since references are inherently constant double& const
is equivalent to double&
. Thus, you get the following instatiation:
struct Foo {
void foo(double&) {}
void foo(double&) {}
};
Here comes the compiler shouting "Dude you can't overload foo
with the same signature".
A more consise error is given by CLANG:
error: multiple overloads of 'foo' instantiate to the same signature 'void (double &&)' void foo(T&) { }
Live Demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With