用于连接编译时序列的模板元编程

Template Metaprogramming for concatenation of compile-time sequences

所以我一直在用我自己的序列 classes 在 C++ 中对编译时序列进行一些试验,但是我 运行 遇到了急切模板实例化的问题,或者在至少我认为是这样。

template <typename SeqA, typename SeqB, int... Items>
class Concat 
    : public std::conditional<SeqA::is_empty() && SeqB::is_empty(),
                 Seq<Items...>, 
                 typename std::conditional<SeqA::is_empty(),
                     typename Concat<SeqA, typename SeqB::Tail, Items..., SeqB::Head>::type, 
                     typename Concat<typename SeqA::Tail, SeqB, Items..., SeqA::Head>::type
                 >::type
              >
{
};

我从编译器收到一条错误消息,指出

main.cpp: In instantiation of ‘Concat<Seq<2, 4, 6, 8, 10>, Seq<>, 1, 3, 5, 7, 9>’:
main.cpp:75:7:   recursively instantiated from ‘Concat<Seq<2, 4, 6, 8, 10>, Seq<3, 5, 7, 9>, 1>’
main.cpp:75:7:   instantiated from ‘Concat<Seq<2, 4, 6, 8, 10>, Seq<1, 3, 5, 7, 9> >’
main.cpp:99:52:   instantiated from here
main.cpp:75:7: error: no type named ‘Tail’ in ‘class Seq<>’
...

concat class 通过从第一个非空序列中抓取一个项目并将其附加到它自己的可变参数来工作。当两个集合都为空时,它 returns 一个以元素作为序列的集合,但错误消息给我的感觉是编译器将实例化 std::conditional 的两个部分,而不管真值。有解决此问题的方法吗?

这太复杂了。我会这样写 Concat:

template <int...> class Seq;
template <typename SeqA, typename SeqB> class Concat;
template <int... Ints1, int... Ints2>
class Concat<Seq<Ints1...>, Seq<Ints2...>>
{
    using type = Seq<Ints1..., Ints2...>;
};

是的,std::conditional需要评估它的所有参数;没有短路发生。这可以通过另一层间接来解决,就像在编程中一样。