Clang可变参数模板特化错误:不可导入的模板参数

时间:2014-09-28 03:37:36

标签: c++ c++11 variadic-templates template-meta-programming specialization

我使用clang ++ - 600.0.51编译以下代码:

template<typename ... Args> struct seq{};
template<typename Seq, size_t c = 1> struct pop_back;

template<typename ... Args> struct pop_back <seq<Args...>,  0>{
    typedef seq<Args...> type;
};
template<typename ... Args, typename T, size_t c> struct pop_back <seq<Args..., T>,  c>{
    typedef typename pop_back<seq<Args...>, c - 1>::type type;
};

我得到一个错误:类模板部分特化包含模板参数       无法推断;永远不会使用这种局部特化[-Werror]

似乎我以错误的方式专注于可变参数模板,但是gcc 4.8.2和vc 2013可以成功编译它。如果我只是如上所述定义pop_back,那么gcc和vc都会被传递。如果我实例化pop_back,它们都会失败。

我的代码不标准吗?如何为此编写解决方法?

1 个答案:

答案 0 :(得分:3)

无法推断

T,因为编译器无法确定参数包Args...的结尾。你需要一个不同的实现。当c减少时,这个连接序列的各个元素。

namespace detail
{
template <typename S1, typename S2>
struct concat_impl;

template <typename... Ts, typename... Us>
struct concat_impl<seq<Ts...>, seq<Us...>>
{
    using type = seq<Ts..., Us...>;
};

template <typename S1, typename S2>
using concat = typename concat_impl<S1, S2>::type;

template <typename Seq, size_t c = 1, typename = void>
struct pop_back;

template <typename T, typename... Args, size_t c>
struct pop_back<seq<T, Args...>,  c, typename std::enable_if<c!=0>::type>
{
    using type = concat<seq<T>, typename pop_back<seq<Args...>, c-1>::type>;
};

template <typename... Args>
struct pop_back<seq<Args...>, 0>
{
    using type = seq<>;
};
} // detail

template <typename Sequence, size_t c>
struct pop_back;

template <typename... Args, size_t c>
struct pop_back<seq<Args...>, c> : detail::pop_back<seq<Args...>, sizeof...(Args) - c>
{ };

Live Demo