1

компилирует следующий код с лязгом ++ - 600.0.51:Clang ошибка VARIADIC специализация шаблона: без выводим параметр шаблона

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.

Является ли мой код нестандартным? как написать обходной путь для этого?

+0

трудно изречение, так как мы не имеем ни малейшего понятия, что 'seq' есть. – WhozCraig

+0

я пропустил определение seq. добавил. – wingfire

ответ

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

+0

Я должен где-то сохранить этот вопрос и поднять его в качестве обоснованной причины, позволяющей вывести 'Args ..., T' (потому что серьезно, единственная причина, по которой это запрещено,« потому что у нее нет [много? ] и просто увеличит сложность »). – Griwes

+0

Вы правы. Я неправильно понял стандарт C++. Если мое понимание верное, ваш concat не работает так, как ожидаете, например, если c равно 1, а Seq - Seq . во всяком случае, я поймаю суть вашего решения, и я могу закончить оставшуюся часть этой проблемы. Большое спасибо! – wingfire

Смежные вопросы