Инициализирующий вектор с переменным шаблоном

#c #templates #vector #variadic-templates #parameter-pack

Вопрос:

В принципе, мне нужна функция шаблона, которая сравнивала бы размер контейнера с некоторой константой. Поэтому мне нужно создать std::вектор контейнеров и проверить, верен ли предикат compSize.

 template < int x, class Container >
bool compSize(Container cont)
{
    return x == cont.size();
}
    
template < int x, class ...Container >
bool compSizeMult(Container ...conts)
{
    std::vector< Container > cvector{ conts... };
    return std::all_of(cvector.cbegin(), cvector.cend(), compSize< x, Container >);
}
 

Но компилятор говорит, что пакет параметров не расширяется при

cvector{ продолжение… };

Также я хотел бы использовать compSizeMult в качестве компаратора для std::сортировать и сделать что-то вроде

 int main()
{
    std::vector< std::vector< int > > vec{{1}, {2}, {3}, {0}, {0}};
    std::sort(vec.begin(), vec.end(), compSizeMult< 0, std::vector< int > >);
}
 

вот почему функция должна принимать несколько аргументов. Я не могу использовать циклы и лямбды в этой задаче, только стандартные алгоритмы

Комментарии:

1. Стандарт гласит, что допустимо использовать шаблон variadic в списке инициализаторов. Другие ответы содержат фрагменты кода, где таким образом используется вариативный шаблон. Но… Это просто не работает

2. Я только что понял, что не могу использовать эту функцию в качестве компаратора

Ответ №1:

У вас есть 2 вариадики в

 std::vector<Container> cvector{ conts... };
 
  • переменная conts , которая имеет свои ... ,
  • Тип Container , у которого нет своего ... (ни в compSize<x, Container> ).

Возможно, ты захочешь std::common_type_t<Container...> .

В C 17 вы можете использовать выражения сгиба:

 template < int x, class ... Containers >
bool compSizeMult(Containersamp;amp;... conts)
{
    return (compSize<x>(conts) amp;amp; ...);
    // or directly: return (conts.size == x amp;amp; ...);
}
 

Я хотел бы использовать compSizeMult в качестве компаратора

Это недопустимый компаратор. Это нарушает строгий слабый порядок.

Комментарии:

1. Значит, я не могу распаковать содержимое в вектор?

2. std::vector<std::common_type_t<Container...>> cvector{ conts... }; должно работать (если есть общий тип, вы не можете смешивать std::vector<int> с std::list<int> с std::вектор<float><float> ). Alternatively, you can std::вектор<std::size_t> размеры{продолжение. размер()…};`