Если у меня есть базовый класс шаблона с методом шаблона:
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;
}
};
Для примера я упрощаю метод: он должен "существовать", только если T == U
Если A это класс:
class A : public S<int> {};
Тогда у меня есть то, что я хочу:
int i = 1;
A a;
a.f(i);
компилируется, но
double d = 2.0;
a.f(d);
не компилируется: ошибка:нет соответствующей функции для вызова 'A :: f (double &)'. Это ожидаемое поведение.
Теперь давайте также унаследуем A от S<double>
:
class A : public S<int>, public S<double> {};
Затем следующий кодне компилируется:
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]
Я ожидал, что двусмысленности нет: f<int>
существует только для S<int>
В ошибке компиляторамы можем заметить, что T известен, когда этот фрагмент кода скомпилирован, но не U (U = U).
Любое объяснение или "обходной путь"?