Я пытаюсь понять , как правильно выбрать шаблон перегруженной функции во время компиляции , но компилятор доставляет мне неприятности.Я могу заставить это работать, но я не понимаю, что происходит.Позвольте мне объяснить.
У меня есть две структуры A и B, как показано ниже.У одного есть специальная функция, а у другого - нормальная.
struct A
{
void special() { std::cout << "special called.\n"; }
};
struct B
{
void normal() { std::cout << "normal called.\n"; }
};
Я хочу иметь механизм, который во время компиляции выбирает правильный перегруженный шаблон функции в зависимости от того, доступна ли специальная функция.У меня запущены две функции, которые принимают структуру в качестве параметра, чтобы они могли вызывать соответствующую функцию.
template<class Func, Func f> struct Sfinae {};
template <typename U>
static void run(U& u, Sfinae<void (U::*)(), &U::special>* = 0)
{
u.special();
}
template <typename U>
static void run(U& u, ...)
{
u.normal();
}
Я проверил это с помощью следующих результатов, с различными результатами:
int main()
{
A a;
run<A>(a, 0); // works
run<A>(a); // ERROR: ambiguous overloaded function
run(a, 0); // ERROR: A has no member normal
run(a); // ERROR: ambiguous overloaded function
B b;
run<B>(b, 0); // works
run<B>(b); // works
run(b, 0); // works
run(b); // works
return 0;
}
Я бы хотел использовать его как run(a)
без каких-либо дополнительных аргументов или <>.Что-то не так с моим кодом, когда он не работает?
Кроме того, мне интересно понять, что здесь происходит и почему это приводит к таким вещам, поэтому мне нужно дать <A>
дляA
но не для B
?Я не знаю, что говорится в стандарте, и если это отличается в разных компиляторах, но, по крайней мере, gcc4.4.4 в Linux и gcc 4.0.1 в Mac работают так, как я описал.
Может кто-нибудь, пожалуйста, пролить немногосвет на это?Спасибо!