Название: SFINAE для методов шаблонных классов
Отправлено: Eugene Efremov от Апрель 09, 2008, 01:35
Имеем следующий пример неработающего кода: struct foo1 { typedef int val; }; struct foo2 { };
template <class foo> struct bar { typename foo::val f() {return 10; } // other... };
int main() { bar<foo1> f1; bar<foo2> f2; // error: no type named `val' in `struct foo2' int i = f1.f(); //f2::f newer used... }
Есть идеи, как можно поизвращаться с enable_if и ему подобными, чтобы заставить это дело компиляться, игнорируя отсутствие foo::val для bar<foo2>?
Название: Re: SFINAE для методов шаблонных классов
Отправлено: Tonal от Апрель 09, 2008, 08:56
#include <iostream>
struct yes { char dummy; }; struct no { yes dummy[2]; };
//Распознование, определён ли в классе typedef val template <class T> struct has_val { template <class Y> struct check { typedef yes res; }; template <class U> static typename check<typename U::val>::res test_val(const U*); static no test_val(...);
enum {value = sizeof(yes) == sizeof(test_val((T*)0))}; };
template <class foo> struct bar { //Выбор возвращаемого значения и selector-а template <class T, bool enable> struct type_select { typedef typename T::val type; typedef const T* selector; };
//Возвращаемое значения и selector по умолчанию template <class T> struct type_select<T, false> { typedef long type; typedef const void* selector; };
typedef typename type_select<foo, has_val<foo>::value>::type ret_type; typedef typename type_select<foo, has_val<foo>::value>::selector selector;
//Основная реализация ret_type f(const foo*) { return 10; }
//Реализация по умолчанию ret_type f(const void*) { return 5; }
//Диспетчер ret_type f() { return f((selector)0); } // other... };
//Тестовый пример using std::cout; using std::endl;
struct foo1 { typedef int val; };
struct foo2 { };
int main() { bar<foo1> f1; bar<foo2> f2; cout<<f1.f()<<endl; cout<<f2.f()<<endl; }
На boost::enable_if сам переводи. :) P.S. Блин, насколько всё же проще писать подобное на Haskell, где встроенное сопоставление с образцом...
Название: Re: SFINAE для методов шаблонных классов
Отправлено: Eugene Efremov от Апрель 09, 2008, 19:09
Спасибо! P.S. Блин, насколько всё же проще писать подобное на Haskell, где встроенное сопоставление с образцом...
Ну дык ёлы-палы... Увидев конструкции, порождаемые этим самозародившимся функциональным франкенштейном, волей-неволей задумаешься — какой казни следует предать Страуструпа и КО а строит ли оно того... :-)
|