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

时间:2015-02-22 15:50:54

标签: c++ templates template-meta-programming

所以我在c ++中用我自己的序列类进行了一些编译时序列的实验,但是我已经遇到了急切的模板实例化的问题,或者至少我认为这样做了#39;它是什么。

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类通过从第一个非空序列中抓取一个项目并将其附加到它自己的可变参数来工作。当两个集合都为空时,它返回一个Set,其中元素作为序列,但错误消息让我感觉编译器将实例化std :: conditional的两个部分而不管真值。有没有办法绕过这种行为?

1 个答案:

答案 0 :(得分:2)

这样做过于复杂。这是我写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需要评估其所有参数;没有发生短路。这可以通过另一层间接来解决,就像在编程中一样。