循环类型定义

问题描述:

我有一个无聊的函数来运行,我想循环通过它来节省这个时间(我有所有的数据),但它需要类型。有没有一种方法来创建一个类型的数组,或者有一些补充时间的事情来做到这一点? (如果有帮助,我有3种类型,并希望针对所有类型的所有类型运行该方法)。要做到这一点循环类型定义

fprintf(stdout, "Testing UTF-32...\n"); 
testUTF<uint32_t, uint32_t>(&testEncs[0], &testEncs[0]); 
testUTF<uint32_t, uint16_t>(&testEncs[0], &testEncs[1]); 
testUTF<uint32_t, uint8_t> (&testEncs[0], &testEncs[2]); 

fprintf(stdout, "Testing UTF-16...\n"); 
testUTF<uint16_t, uint32_t>(&testEncs[1], &testEncs[0]); 
testUTF<uint16_t, uint16_t>(&testEncs[1], &testEncs[1]); 
testUTF<uint16_t, uint8_t> (&testEncs[1], &testEncs[2]); 

fprintf(stdout, "Testing UTF-8...\n"); 
testUTF<uint8_t, uint32_t>(&testEncs[2], &testEncs[0]); 
testUTF<uint8_t, uint16_t>(&testEncs[2], &testEncs[1]); 
testUTF<uint8_t, uint8_t> (&testEncs[2], &testEncs[2]); 
+2

我的直觉告诉我,这可以通过模板元编程来解决。 – Nawaz

+0

我的也是,但它也涉及到定义。这似乎是一个混乱的事情要做。 – Jookia

template <int I> struct UType; 
template <> struct UType<0> { typedef uint32_t Type; }; 
template <> struct UType<1> { typedef uint16_t Type; }; 
template <> struct UType<2> { typedef uint8_t Type; }; 
static const int n_types = 3; 

template <int A,int B> 
struct Test { 
    typedef typename UType<A>::Type AType; 
    typedef typename UType<B>::Type BType; 
    static void test() 
    { 
    testUTF<AType,BType>(&testEncs[A],&testEncs[B]); 
    Test<A,B+1>::test(); 
    } 
}; 

template <int A> 
struct Test<A,n_types> { 
    static void test() { Test<A+1,0>::test(); } 
}; 

template <> 
struct Test<n_types,0> { 
    static void test() { } 
}; 

void testAll() 
{ 
    Test<0,0>::test(); 
} 
+0

看起来不错,但我想我只是在外部生成一个展开的循环。 – Jookia

+0

编辑起来就像一个魅力。惊人! +1 – Stephan

+0

经过大量的评估,我想我会用这个。 – Jookia

一种方式是写另一个程序(在你喜欢的lanugage)生成必要为这个测试的C++代码。您可以将此代码生成器构建到您的构建系统中,或者只运行一次并保存输出的C++代码。

+0

这可能是我最终看到的,因为它已经是外部的了。 – Jookia

您可以递归地调用测试。 (这不是你的测试看起来像,但它可以做相同)

template<typename Next, typename Impl> 
struct Tester 
{ 
    template<typename FwdIter> 
    static void Test(FwdIter first, FwdIter last) 
    { 
     for(FwdIter it = first;it != last; ++it) 
      Impl::TestImpl(*first, *it); 
     Next::Test(first, last); 
    } 
}; 

struct EndTest 
{ 
    template<typename FwdIter> 
    static void Test(FwdIter first, FwdIter last) { } 
}; 

template<typename Next> 
struct TestA : Tester<Next, TestA<Next>> 
{ 
    static void TestImpl(int a, int b) 
    { 
     std::cout << "A" << a << b <<"\n"; 
    } 
}; 

template<typename Next> 
struct TestB : Tester<Next, TestB<Next>> 
{ 
    static void TestImpl(int a, int b) 
    { 
     std::cout << "B" << a << b <<"\n"; 
    } 
}; 

int main() 
{ 
    TestA<TestB<EndTest>> test; 
    std::array<int, 3> values = {1, 2, 3}; 
    test.Test(values.begin(), values.end()); 
    return 0; 
} 

另一种工具,通过类型串走(我喜欢的类型类):

#include <stdint.h> 
#include <typeinfo> 
#include <iostream> 

// typeclass 

/* 
* Concept: 
* struct typedseq_traits<T> 
* { 
*  enum { is_empty = 0 }; 
*  static SomeType head(const T &); 
*  static TailTypes tail(const T &); // typedseq_traits<TailTypes> 
* } 
*/ 

template<class T> 
struct typedseq_traits; 


template<class T, class F, int is_empty> 
struct typedseq_foreach_step; 

template<class T, class F> 
struct typedseq_foreach_step<T,F,1> 
{ 
    static void walk(F &func, const T &seq) 
    {} 
}; 

template<class T, class F> 
struct typedseq_foreach_step<T,F,0> 
{ 
    static void walk(F &func, const T &seq) 
    { 
     func(typedseq_traits<T>::head(seq)); 
     typedseq_foreach(func, typedseq_traits<T>::tail(seq)); 
    } 
}; 


template<class T, class F> 
void typedseq_foreach(F &func, const T &seq) 
{ 
    typedseq_foreach_step<T,F,typedseq_traits<T>::is_empty>::walk(func, seq); 
} 

// instances 

struct typelist_empty {}; 

template<class H, class T> 
struct typelist_cons {}; 

template<> 
struct typedseq_traits<typelist_empty> 
{ 
    enum { is_empty = 1 }; 
}; 

template<class H, class T> 
struct typedseq_traits<typelist_cons<H,T> > 
{ 
    enum { is_empty = 0 }; 
    static H head(const typelist_cons<H,T> &seq) { return H(); } 
    static T tail(const typelist_cons<H,T> &seq) { return T(); } 
}; 

// usage 

typedef typelist_cons<uint8_t, typelist_cons<uint16_t, typelist_cons<uint32_t, typelist_empty> > > mylist; 

template<class T1> 
struct func2 
{ 
    template<class T2> 
    void operator()(T2) 
    { 
     std::cerr << typeid(T1).name() << ", " << typeid(T2).name() << std::endl; 
    } 
}; 

struct func1 
{ 
    template<class T1> 
    void operator()(T1) 
    { 
     func2<T1> f; 
     typedseq_foreach(f, mylist()); 
    } 
}; 

int main() 
{ 
    func1 f; 
    typedseq_foreach(f, mylist()); 
}