Но это не сработает.
С вашим первым фрагментом Test
, поскольку std::vector
имеет два параметра шаблона, value_type
и allocator_type
, мы должны указать наличие этих параметров шаблона в объявлении T
используя параметры шаблона шаблона следующим образом.
Здесь я использую переменную, и тогда T<U...>
становится законным для
T = std::vector
и ошибки компиляции устранены.
как мне написать мою вставку?
Следующий код также показывает пример реализации Test::insert
.
Поскольку этот метод может принимать ссылки как lvalue, так и rvalue в C ++ 11 и более поздних версиях, здесь я применяю ссылку пересылки (то, что Скотт Мейерс называет универсальным ссылка ,) на него.
При таком подходе нам не нужно указывать тип значения Test::list
в определении Test::insert
, а передача неправильных типов в Test::insert
вызывает ошибки компиляции.
Если вам нужен тип значения std::vector
, доступен тип элемента std::vector::value_type
:
template <template<class...> class T, class ...U>
class Test
{
T<U...> list;
public:
template<class ...V>
void insert(V&& ...element) {
list.insert(std::forward<V>(element)...);
}
typename T<U...>::iterator begin() noexcept {
return list.begin();
}
typename T<U...>::iterator end() noexcept {
return list.end();
}
using value_type = typename T<U...>::value_type;
};
Это пример использования с std::vector
:
DEMO (std :: vector)
static_assert(
std::is_same<Test<std::vector, int>::value_type, int>::value, "oops!"); // OK.
Test<std::vector, int> test; // OK
test.insert(test.end(), 11);
test.insert(test.end(), 99);
for(auto it = test.begin(); it != test.end(); ++it){
std::cout << *it << std::endl;
}
В качестве другого примера этот класс-оболочка также работает с std::map
следующим образом:
ДЕМО (std :: map)
static_assert(
std::is_same<Test<std::map, int, int>::value_type, std::pair<const int, int>>::value, "oops!"); // OK.
Test<std::map, int, int> test; // OK
test.insert(std::make_pair(1, 11));
test.insert(std::make_pair(2, 99));
for(auto it = test.begin(); it!= test.end(); ++it){
std::cout << it->first << ", " << it->second << std::endl;
}
Наконец, это исправленная версия вашего второго фрагмента:
DEMO (std :: vector)
DEMO (std :: set)
template <class T>
class Test
{
T list;
public:
template<class ...V>
void insert(V&& ...element) {
list.insert(std::forward<V>(element)...);
}
typename T::iterator begin() noexcept {
return list.begin();
}
typename T::iterator end() noexcept {
return list.end();
}
using value_type = typename T::value_type;
};