2015-04-06 6 views
1

Я пытаюсь создать полиморфный контейнер, работающий с вариативными шаблонами. Контейнер инициализируетсяC++ variadic template

container<tag, std::string, int, int, int> m; 

Я хочу использовать следующий синтаксис:

auto& v2 = m.find<2, 3, 4>(255, 0, 0); 

шаблона аргументы будут указывать «столбцы» и для параметров, я хочу соответствующий тип можно ожидать компилятором.

Для одного аргумента шаблона (find<2>(255)) я использовал:

template < int idx > const typename value_type & 
find(const typename std::tuple_element<idx, typename value_type>::type &key) { 
    const std::size_t row_id = getId<idx>(key); 
    return data_.at(row_id); 
} 

Это работало отлично, так что я хотел, чтобы расширить его следующим образом:

template<int ... idx> const typename value_type & 
find(const typename std::tuple_element<idx..., typename value_type>::type &keys...) { 
    const std::size_t row_id = getId<idx...>(keys); 
    return data_.at(row_id); 
} 

Что не работает вообще. Ошибка компиляции C2660 - find: функция не принимает 3 аргумента. Может кто-нибудь объяснить мне, что мне здесь не хватает? Спасибо.

EDIT:

Заголовок container класса

template<typename ... Arguments> class container 

value_type упоминается в

typedef std::tuple <Arguments...> value_type; 

EDIT2: ответ TC был действительно полезным, хотя я все еще ползет через мои ошибки с вариативными шаблонами. В настоящее время:

enum tag {/*...*/} 

int main() { 
    container<tag, std::string, int, int, int> m; 
} 

template<typename ... Arguments> class container { 
public: 
    typedef std::tuple <Arguments...> value_type; 
    std::vector<value_type> data_; 

    template <int id> void narrowRange(
    std::set<std::size_t> & range, 
    const typename std::tuple_element<id, typename value_type>::type &key) 
    { 
    // all commented out 
    } 

    template <int id, int ... idx> 
    void narrowRange(
    std::set<std::size_t> & range, 
    const typename std::tuple_element<id, typename value_type>::type & key, 
    const typename std::tuple_element<idx, typename value_type>::type & ... keys) // <- 
    { 
    narrowRange<idx...>(range, keys...); 
    // rest commented out 
    } 

Вызвать внутреннюю ошибку в MSVS2013 на отмеченной строке. Любые предложения, почему бы вас оценили.

ответ

2

Во-первых, value_type не нужен typename - Я уверен, что грамматика фактически запрещает его.

Во-вторых, вы расширяете idx слишком рано, а также неправильно пытаетесь развернуть keys в декларации. (Этот второй ... фактически анализируется как varargs в стиле C.) Вы также не расширяете пакет keys в теле функции. Предполагая, что вы хотите find<2, 3, 4>(255, 0, 0) вызвать getId<2, 3, 4>(255, 0, 0), правильный синтаксис

template<int ... idx> const value_type & 
find(const typename std::tuple_element<idx, value_type>::type &... keys) { 
    const std::size_t row_id = getId<idx...>(keys...); 
    return data_.at(row_id); 
} 
+0

Спасибо, что помогли. Тем не менее, у меня возникла проблема, которая выглядит очень знакомой: 'template void erase (const typename std :: tuple_element :: type & ... keys) { \t \t const std: : size_t row_id = getId (ключи ...); \t \t/* и т. Д. * /} 'Failing on" не содержит пакет параметров ", и я действительно не знаю, почему, поскольку он выглядит так же, как и предыдущая функция для меня – eghuro

+0

@eghuro Пожалуйста, отправьте сообщение [MCVE] (http : //stackoverflow.com/help/mcve) в качестве редактирования вашего вопроса. –

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