Re: Вызов функций по спискам типов
От: Кодт Россия  
Дата: 25.11.09 20:11
Оценка: +1
Здравствуйте, <Аноним>, Вы писали:

А>Возможно ли с помощью шаблонной магии сделать аналогичный результат вывода main() без перечисления всех возможных сочетаний типов из списков?(Т.е что то типа одного вызова f(List2,List1) ) Использование локи не обязательно-просто для примера.


Да, смотри boost/mpl.

Я не шибко разбираюсь в том, как писать навороченные формулы там, поэтому вместо того, чтобы сделать декартово произведение и пробежаться по нему, устроил двойной цикл на велосипеде
#include <boost/mpl/vector.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/transform.hpp>

#include <iostream>

namespace bm = boost::mpl;

// коллекции типов
typedef bm::vector<char,int,double> va;
typedef bm::vector<short,float> vb;

// целевая функция
template<class A, class B> void f() { std::cout << __FUNCSIG__ << std::endl; }

// обёртка типа (мало ли, вдруг он не DefaultConstructible окажется...)
template<class T> struct wrap { typedef wrap type; }; //TODO: bm::quote, bm::identity...

// обёртываем наши коллекции перед итерированием
typedef bm::transform< va, wrap<bm::_1> >::type wa; // bm::vector< wrap<char>, wrap<int>, wrap<double> >
typedef bm::transform< vb, wrap<bm::_1> >::type wb;

// для данного элемента первой коллекции...
template<class A> struct fab
{
    // и данного элемента второй коллекции...
    template<class B> void operator()(wrap<B>) const { f<A,B>(); } // вызываем целевую функцию
};

struct fa
{
    // для данного элемента первой коллекции...
    template<class A> void operator()(wrap<A>) const
    {
        bm::for_each<wb>(fab<A>()); // устраиваем забег по второй
    }
};

int main()
{
    bm::for_each<wa>(fa()); // устраиваем забег по первой коллекции
}
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
Вызов функций по спискам типов
От: Аноним  
Дата: 25.11.09 19:07
Оценка:
Всем привет!
Возможно ли с помощью шаблонной магии сделать аналогичный результат вывода main() без перечисления всех возможных сочетаний типов из списков?(Т.е что то типа одного вызова f(List2,List1) ) Использование локи не обязательно-просто для примера.
#include <iostream>  
#include <loki/Typelist.h>

typedef LOKI_TYPELIST_3(char,int,double) List1;
typedef LOKI_TYPELIST_2(short,float) List2;


template <class A,class B>
void f()
{
 std::cout << typeid(A).name() << " " << typeid(B).name() << std::endl;
}

void main()
{
 f<short,char>();
 f<short,int>();
 f<short,double>();
 
 f<float,char>();
 f<float,int>();
 f<float,double>();
 
}
Re[2]: Вызов функций по спискам типов
От: AlexTrump  
Дата: 26.11.09 19:09
Оценка:
К>Да, смотри boost/mpl.

Ну вот,опять без великого и ужасного не обойтись
Я вот так сделал
#include <iostream>  
#include "loki/Typelist.h"

typedef LOKI_TYPELIST_3(char,int,double) List1;
typedef LOKI_TYPELIST_2(short,float) List2;


template <typename A,typename B>
void func()
{
 std::cout << typeid(A).name() << " " << typeid(B).name() << std::endl;
}

template <typename A,typename ListB>
struct OneToMany
{
 static void f()
 {
  func<A,ListB::Head>();
  OneToMany<A,ListB::Tail>::f();
 }
};

template<typename A>
struct OneToMany<A,Loki::NullType>
{
 static void f() {}
};

template <typename ListA,typename ListB>
struct ManyToMany
{
 static void f()
 {
  OneToMany<ListA::Head,ListB>::f();
  ManyToMany<ListA::Tail,ListB>::f();
 }
}; 

template<typename B>
struct ManyToMany<Loki::NullType,B>
{
 static void f(){}
};

void main()
{
 ManyToMany<List2,List1>::f();
}
Re[3]: Вызов функций по спискам типов
От: Кодт Россия  
Дата: 26.11.09 19:58
Оценка:
Здравствуйте, AlexTrump, Вы писали:

К>>Да, смотри boost/mpl.


AT>Ну вот,опять без великого и ужасного не обойтись

Ну, можно и на Локи — просто в бусте уже дофига понаписано инструментов метапрограммирования. Считай, весь лисп
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.