RedLord Да, все работает. Там есть ссылка на статью. Прочитал - понравилось Очень тонкий и изящный способ
_DEN_ странно. Comeau, Intel: more than one instance of overloaded function "omni::test_for_swap а вот если вместо template <class T> double test_for_swap(const T&, ...); объявить double test_for_swap(...); все пучком
RedLord В таком случае не работает на 8.0 Че-то камю кстати гонит - там вроде все по стандарту получаицо. Действительно странно.
_DEN_ Код (Text): template <class T> char test_for_swap(const T&, member_wrapper<void (T::*)(T&), &T::swap>* p = 0); template <class T> double test_for_swap(const T&, ...); ... test_for_swap(t) не уверен. дефолтный аргумент участвует в определении жизнеспособности функции, а при определении наилучшей - нет. по первому аргументу (const T&) получается неопределенность P.S. поправьте, если не так
RedLord А как же SFINAE? Да и ... имеет самый низкий приоритет при матчинге. У шаблона приоритет выше - судя по статье, на которую ссылка с RSDN тут как раз все по понятиям.
_DEN_ SFINAE позволяет компилятору безболезненно удалить из набора первую функцию, если неудался вывод для member_wrapper (другими словами у T нет мембера swap или swap не есть void (T::*)(T&) ). в противном случае в наборе остается две функции и между ними нужно выполнить разрешение перегрузки Nouzui 13.3.3 Best Viable Function (ISO/IEC 14882:2003)
RedLord Ну так шаблон имеет более высокий приоритет. Тоесть например: Код (Text): template <class T> void foo(int i, T* t = 0); void foo(int i, ...); int a = 10; foo(a); // Будет вызвана первая функция. Разве не так?
_DEN_ 1. там оба темплейта 2. приоритет темплейта наоборот ниже: RedLord что-то я в 13.3.3 не нашел.. в 13.3.2 есть: впрочем, к теме это мало относится, поскольку второй аргумент в данном случае задан явно, а вот то, что приоритет ... ниже аргумента с определенным типом, верно:
Nouzui Ага, значит меня просто MSVC 8.0 обманывает. Вот такой код. Код (Text): template <class T> void foo(T t, T* p = 0) { } template <class T> void foo(T t, ...) { } int main() { int x = 0; foo(x); return 0; } Поганый МСВЦ вызывает 1-ю, а камю говорит вот что: "ComeauTest.c", line 14: error: more than one instance of overloaded function "foo" matches the argument list, the choices that match are: function template "void foo(T, T *)" function template "void foo(T, ...)" The argument types that you used are: (int) foo(x); ^
вызывается вторая.. а про второй случай мы сейчас и спорим. я пока не понял, что стандарт говорит по этому поводу..
Nouzui Код (Text): template <class T> void foo(T t, T* p = 0) { } template <class T> void foo(T t, ...) { } int main() { int x = 0; foo(x); return 0; } насколько я понял, при foo(x) дефолтные аргументы и ... отбрасываются и разрешение перегрузки проходит только по первому параметру - а он у обоих функций с одним рангом.
RedLord да я уже и сам понял, что стормозил по поводу "второй аргумент в данном случае задан явно" выходит, MS не зря добавила свою __if_exists?
ну ладно, раз вопрос стоит только в разрешении темплейтов, можно так: Код (Text): template <class T, T val> struct member_wrapper{}; template <class T> char test_for_swap(const T&, const T&, member_wrapper<void (T::*)(T&), &T::swap>* p = 0); template <class T> double test_for_swap(const T&, ...); template <class T> struct has_member_swap { static T t; static const bool value = (1 == sizeof(test_for_swap(t, t))); }; на MS 8.0 прокатывает за исключением случаев, когда проверяемый мембер инкапсулирован (private или protected) с последним случаем, похоже, вообще задница.. кстати, похоже и мелкомягкие расширения тут тоже не помогут