循环类型定义
问题描述:
我有一个无聊的函数来运行,我想循环通过它来节省这个时间(我有所有的数据),但它需要类型。有没有一种方法来创建一个类型的数组,或者有一些补充时间的事情来做到这一点? (如果有帮助,我有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]);
答
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();
}
答
一种方式是写另一个程序(在你喜欢的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());
}
我的直觉告诉我,这可以通过模板元编程来解决。 – Nawaz
我的也是,但它也涉及到定义。这似乎是一个混乱的事情要做。 – Jookia