У меня проблема, очень похожая на проблему, представленную Морфеусом, в следующем вопросе:
Перегруженный указатель функции-члена на шаблон
Решение, предложенное Ричардом Корденом, требует, чтобы пользователь явно указал тип параметра функции, чтобы различать его среди перегрузок. Однако это решение, похоже, не работает с перегрузками с различным количеством аргументов одного и того же типа.
Рассмотрим этот пример (полученный из исходного вопроса):
template <typename T>
class A
{
public:
template<class Arg1>
void connect(void (T::*f)(Arg1))
{
//Do some stuff
}
template<class Arg1, class Arg2>
void connect(void (T::*f)(Arg1,Arg2))
{
//Do some stuff
}
void connect(void (T::*f)())
{
//Do some stuff
}
};
class GApp
{
public:
void foo() {}
void foo(double d) {}
void foo(double d1, double d2) {}
};
int main ()
{
A<GApp> a;
a.connect (&GApp::foo); // foo () - OK
a.connect<double> (&GApp::foo); // foo (double) - FAIL
a.connect<double,double> (&GApp::foo); // foo (double,double) - OK
}
GNU G ++ 3.4.5 и MSVC 2008 не компилируют приведенный выше код, так как оба представляют похожие сообщения об ошибках:
test.cpp: In function `int main()':
test.cpp:36: error: call of overloaded `connect(<unknown type>)' is ambiguous
test.cpp:7: note: candidates are: void A<T>::connect(void (T::*)(Arg1)) [with Arg1 = double, T = GApp]
test3.cpp:13: note: void A<T>::connect(void (T::*)(Arg1, Arg2)) [with Arg1 = double, Arg2 = double, T = GApp]
Мне известно о некоторых обходных приемах, которые могут заставить его скомпилировать, например, назначении указателя на переменную того же типа (например, void (GApp::*tmp)(double) = &GApp::foo;
) или использовании более явной формы при вызове функции подключения (например, connect((void (GApp::*)(double))(&GApp::foo));
).
Однако я предпочитаю первое решение и хотел бы знать, почему оно не работает.
Заранее спасибо!