1

我编译以下与铛++代码 - 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; 
}; 

和我收到一个错误:类模板部分特例包含模板参数 不能推导出;这部分专业化将永远不会使用[ - 错误]

似乎我专门错误的方式的可变参数模板,但gcc 4.8.2和vc 2013可以成功地编译它。如果我只是像上面那样定义pop_back,那么就会传递gcc和vc。如果我实例化pop_back,所有这些都失败了。

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

+0

甚难,因为我们不知道什么'seq'是。 – WhozCraig 2014-09-28 03:48:38

+0

我错过了seq的定义。添加它。 – wingfire 2014-09-28 09:50:04

回答

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

+0

如果有人可以建议不使用'enable_if'的版本,那将非常感激。 – 0x499602D2 2014-09-28 04:46:54

+0

我必须将这个问题保存在某个地方,并将其作为允许推导出'Args ...,T'的正当理由提出来(因为严重的是,这个被拒绝的唯一原因是“因为它没有[很多? ]用例,并会增加复杂性“)。 – Griwes 2014-09-28 09:57:52

+0

你说得对。我误解了C++标准。如果我的理解是正确的,你的concat不能按预期工作,例如,如果c是1并且Seq是Seq 。无论如何,我抓住你的解决方案的重点,我可以完成这个问题的其余部分。万分感谢! – wingfire 2014-09-28 10:04:55