stl
/
std
来自C++的库,因为我正在为一个只有可用的嵌入式操作系统编程。
gcc
4.4.4
用裸露的C++,所以,没有
std::tuple
,
std::forward
,
std::apply
或
std::anything_else
为了帮助理解元泛型生成的代码,我提供了一个用
clang
因为它可以显示生成的
template-meta-programming
metaprogramming
代码。
template<int ...>
struct MetaSequenceOfIntegers { };
template<int AccumulatedSize, typename Tn, int... GeneratedSequence>
struct GeneratorOfIntegerSequence;
template<int AccumulatedSize, typename Grouper, typename Head, typename... Tail, int... GeneratedSequence>
struct GeneratorOfIntegerSequence< AccumulatedSize, Grouper( Head, Tail... ), GeneratedSequence... >
{
typedef typename GeneratorOfIntegerSequence
< AccumulatedSize + sizeof(Head), Grouper( Tail... ), AccumulatedSize, GeneratedSequence...
>::type type;
};
template<int AccumulatedSize, typename Grouper, int... GeneratedSequence>
struct GeneratorOfIntegerSequence<AccumulatedSize, Grouper(), GeneratedSequence...>
{
typedef MetaSequenceOfIntegers<GeneratedSequence...> type;
};
template<int ...Sequence>
void intergers_sequencer_generator(MetaSequenceOfIntegers<Sequence...>) {
int array[] = {Sequence...};
}
int main(int argc, char const *argv[]) {
intergers_sequencer_generator( GeneratorOfIntegerSequence< 0, int(char, int, char) >::type() );
return 0;
}
我只是在用
int array[] = {Sequence...}
做示范。实际使用的代码如下:
template<typename ReturnType, typename... Tn>
class Closure
{
// ... other code
template<int ...Sequence>
ReturnType _run(MetaSequenceOfIntegers<Sequence...>) {
return _function_entry_pointer( get_nth_function_argument_on_address<Sequence, Tn>()... );
}
// ... other code
}
这就产生了这个吼声,对于像
create_functor( &function1, 'a', 10, 'b' )
:
template <int ...Sequence> char _run(MetaSequenceOfIntegers<Sequence...>);
template<> char _run<<5, 1, 0>>(MetaSequenceOfIntegers<5, 1, 0>) {
return this->_function_entry_pointer(
this->get_nth_function_argument_on_address<5, const char *>(),
this->get_nth_function_argument_on_address<1, const char *>(),
this->get_nth_function_argument_on_address<0, char>()
);
}
// and much more
我们可以使用
:
$ clang++ -Xclang -ast-print -fsyntax-only generator.cpp > expanded.cpp
template <int ...> struct MetaSequenceOfIntegers {
};
template<> struct MetaSequenceOfIntegers<<5, 1, 0>> {
};
template <int AccumulatedSize, typename Tn, int ...GeneratedSequence> struct GeneratorOfIntegerSequence
template<> struct GeneratorOfIntegerSequence<0, int (char, int, char), <>> {
typedef typename GeneratorOfIntegerSequence<0 + sizeof(char), int (int, char), 0>::type type;
}
template<> struct GeneratorOfIntegerSequence<1, int (int, char), <0>> {
typedef typename GeneratorOfIntegerSequence<1 + sizeof(int), int (char), 1, 0>::type type;
}
template<> struct GeneratorOfIntegerSequence<5, int (char), <1, 0>> {
typedef typename GeneratorOfIntegerSequence<5 + sizeof(char), int (), 5, 1, 0>::type type;
}
template<> struct GeneratorOfIntegerSequence<6, int (), <5, 1, 0>> {
typedef MetaSequenceOfIntegers<5, 1, 0> type;
};
template <int AccumulatedSize, typename Grouper, typename Head, typename ...Tail, int ...GeneratedSequence> struct GeneratorOfIntegerSequence<AccumulatedSize, type-parameter-0-1 (type-parameter-0-2, type-parameter-0-3...), <GeneratedSequence...>> {
typedef typename GeneratorOfIntegerSequence<AccumulatedSize + sizeof(Head), Grouper (Tail...), AccumulatedSize, GeneratedSequence...>::type type;
};
template <int AccumulatedSize, typename Grouper, int ...GeneratedSequence> struct GeneratorOfIntegerSequence<AccumulatedSize, type-parameter-0-1 (), <GeneratedSequence...>> {
typedef MetaSequenceOfIntegers<GeneratedSequence...> type;
};
template <int ...Sequence> void intergers_sequencer_generator(MetaSequenceOfIntegers<Sequence...>) {
int array[] = {Sequence...};
}
template<> void intergers_sequencer_generator<<5, 1, 0>>(MetaSequenceOfIntegers<5, 1, 0>) {
int array[] = {5, 1, 0};
}
int main(int argc, const char *argv[]) {
intergers_sequencer_generator(GeneratorOfIntegerSequence<0, int (char, int, char)>::type());
return 0;
}
元编程列表的生成顺序与我需要的相反。而不是
int array[] = {5, 1, 0}
,应该是
int array[] = {0, 1, 5}
.
我成功地按照正确的顺序生成了列表,只是在示例代码中更改了这一行:
< AccumulatedSize + sizeof(Head), Grouper( Tail... ), GeneratedSequence..., AccumulatedSize
// to -->
< AccumulatedSize + sizeof(Head), Grouper( Tail... ), AccumulatedSize, GeneratedSequence...
但是让我们假设我不能这样做,因为列表是从第三部分输入的,我没有控制权。如何反转参数包
<5, 1, 0>
到
<0, 1, 5>
在第一次尝试中,我尝试使用与生成整数列表相同的策略,但无法编译:
template<int ...>
struct MetaSequenceOfIntegers { };
template<int AccumulatedSize, typename Tn, int... GeneratedSequence>
struct GeneratorOfIntegerSequence;
template<int AccumulatedSize, typename Grouper, typename Head, typename... Tail, int... GeneratedSequence>
struct GeneratorOfIntegerSequence< AccumulatedSize, Grouper( Head, Tail... ), GeneratedSequence... >
{
typedef typename GeneratorOfIntegerSequence
< AccumulatedSize + sizeof(Head), Grouper( Tail... ), AccumulatedSize, GeneratedSequence...
>::type type;
};
template<int AccumulatedSize, typename Grouper, int... GeneratedSequence>
struct GeneratorOfIntegerSequence<AccumulatedSize, Grouper(), GeneratedSequence...>
{
typedef MetaSequenceOfIntegers<GeneratedSequence...> type;
};
// The new code starts here
template<int ...>
struct MetaSequenceReversed { };
template<typename Tn, int... GeneratedSequence>
struct ReversorOfIntegerSequence;
template<typename Grouper, int Head, int... Tail, int... GeneratedSequence>
struct ReversorOfIntegerSequence< Grouper( Head, Tail... ), GeneratedSequence... >
{
typedef typename ReversorOfIntegerSequence
< Grouper( Tail... ), GeneratedSequence...
>::type type;
};
template<typename Grouper, int... GeneratedSequence>
struct ReversorOfIntegerSequence<Grouper(), GeneratedSequence...>
{
typedef MetaSequenceReversed<GeneratedSequence...> type;
};
template<int ...ReversedSequence>
void intergers_sequencer_reversor(MetaSequenceReversed<ReversedSequence...>) {
int reversed_array[] = {ReversedSequence...};
}
template<int ...Sequence>
void intergers_sequencer_generator(MetaSequenceOfIntegers<Sequence...>) {
int array[] = {Sequence...};
intergers_sequencer_reversor( ReversorOfIntegerSequence< int(Sequence...) >::type() );
}
int main(int argc, char const *argv[])
{
intergers_sequencer_generator( GeneratorOfIntegerSequence< 0, int(char, int, char) >::type() );
return 0;
}
当我尝试构建它时,出现了以下错误:
generator.cpp:29:35: error: template argument for template type parameter must be a type
struct ReversorOfIntegerSequence< Grouper( Head, Tail... ), GeneratedSequence... >
^~~~~~~~~~~~~~~~~~~~~~~~
generator.cpp:25:19: note: template parameter is declared here
template<typename Tn, int... GeneratedSequence>
^
generator.cpp:50:62: error: template argument for template type parameter must be a type
intergers_sequencer_reversor( ReversorOfIntegerSequence< int(Sequence...) >::type() );
^~~~~~~~~~~~~~~~
generator.cpp:25:19: note: template parameter is declared here
template<typename Tn, int... GeneratedSequence>
^
参考文献:
-
Variadic templates, parameter pack and its discussed ambiguity in a parameter list
-
"unpacking" a tuple to call a matching function pointer
-
Can we see the template instantiated code by C++ compiler
-
Build function parameters with variadic templates
-
How to reverse the order of arguments of a variadic template function?