If I have a template base class with a template method :
template <typename T>
class S
{
public:
template <typename U>
void f(U p, typename enable_if<is_same<T, U> >::type*dummy = 0)
{
std::cout << p << std::endl;
}
};
For the example, I simplify the method : it must “exists” only if T == U
If A is this class:
class A : public S<int> {};
Then I have what I want:
int i = 1;
A a;
a.f(i);
compiles, but
double d = 2.0;
a.f(d);
doesn’t compile : error: no matching function for call to ‘A::f(double&)’
It is the expected behavior.
Now let’s A inherit from S<double> also :
class A : public S<int>, public S<double> {};
Then the following code doesn’t compile:
int i = 1;
A a;
a.f(i);
error: request for member ‘f’ is ambiguous error: candidates are: template<class U> void S::f(U, typename boost::enable_if<boost::is_same<T, U>, void>::type*) [with U = U, T = double] error: template<class U> void S::f(U, typename boost::enable_if<boost::is_same<T, U>, void>::type*) [with U = U, T = int]
I expected there is no ambiguity : f<int> exists only for S<int>
In the compiler error, we can notice that T is known when this piece of code is compiled, but not U (U = U).
Any explanation or “workaround” ?
Try this:
…or alternatively inject the function into
A, e.g.