Re: можно ли такое на шаблонах провернуть...
От: Sm0ke Россия ksi
Дата: 20.12.06 14:53
Оценка:
Здравствуйте, ламмму, Вы писали:

Л>Привет!

Л>значит есть вот что:
Л>
Л>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;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.