Здравствуйте, ламмму, Вы писали:
Л>Привет!
Л>значит есть вот что:
Л>Л>enum some_enum { en1, en2, en3 };
Л>void foo(some_enum e) {...}
Л>
Л>в зависимости от значения параметра foo ведет себя совершенно по разному (т.е. банальный switch)
Л>Л>void foo(some_enum e)
Л>{
Л> swith (e) {
Л> case en1: foo_en1_implementation(); break;
Л> ...
Л> default: throw not_implemented;
Л> }
Л>}
Л>
Л>не люблю писать switch принципильно
поэтому делаю так:
Л>Л>enum some_enum { en1, en2, en3 };
Л>template <some_enum>
Л>void foo()
Л>{
Л> std::cout << "unspecified" << std::endl;
Л>}
Л>template <>
Л>void foo<en1>()
Л>{
Л> std::cout << "en1 implementation" << std::endl;
Л>}
Л>int main()
Л>{
Л> foo<en1>();
Л> foo<en2>();
Л> return 0;
Л>}
Л>
Л>все как бы работает... но как-то некрасиво писать foo<en1>()
Л>хочется вот так:
Л>foo(en1); // но внутри swithc не писать
Л>Возможно ли такое сотворить ?
Л>ЗЫ: никакого runtime не будет... foo будет вызываться только так foo(/*en1 | en2 | en3*/) т.е. компилятор точно знает значение передаваемого аргумента
Можно сделать массив ф-йций:
enum some_enum { en1, en2, en3 };
template <some_enum>
void foo()
{
std::cout << "unspecified" << std::endl;
}
template <>
void foo<en1>()
{
std::cout << "en1 implementation" << std::endl;
}
typedef void (*hfn)(some_enum);
hfn foo_array[] =
{
&foo<en1>,
&foo<en2>,
&foo<en3>
};
inline void foo(some_enum se)
{
return foo_array[se]();
}
void main()
{
foo_array[en1]();
foo(en2);
}
а можно через Loki::Typelist
#include "Loki/HierarchyGenerators.h"
enum some_enum { en1, en2, en3 };
template <some_enum>
void foo()
{
std::cout << "unspecified" << std::endl;
}
template <>
void foo<en1>()
{
std::cout << "en1 implementation" << std::endl;
}
template <class Enum, Enum Value>
struct Enum2Type
{
typedef Enum type;
};
template <class ResultType>
struct helper
{
template <class T, class B>
class unit;
template <class Enum, Enum SE, class B>
class unit<Enum2Type<Enum, SE>, B> : public B
{
protected:
static ResultType unit_call(some_enum se)
{
if (se == SE) return foo<SE>();
return B::unit_call(se);
}
};
template <class Enum, Enum SE>
class unit<Enum2Type<Enum, SE>, Loki::EmptyType>
{
protected:
static ResultType unit_call(some_enum se)
{
return foo<SE>();
}
};
};
struct cfoo : Loki::GenLinearHierarchy
<
Loki::TL::MakeTypelist
<
Enum2Type<some_enum, en1>,
Enum2Type<some_enum, en2>,
Enum2Type<some_enum, en3>
>::Result,
helper<void>::unit
>
{
static void call(some_enum se)
{
return unit_call(se);
}
};
int _tmain()
{
/*foo<en1>();
foo<en2>();*/
cfoo::call(tmp10::en1);
cfoo::call(tmp10::en2);
return 0;
}