Объединение свойств контейнера

51
5

Я хочу построить черты, которые будут отвечать на такие вопросы, как is_vector, is_list и т.д. Проблема заключается в том, что я должен сделать две версии каждого, а именно шаблон шаблона один:

template<template<class,class> class C>
struct is_vector1 : std::false_type { };

template<>
struct is_vector1<std::vector> : std::true_type { };

и простые аргументы шаблона:

template<class T>
struct is_vector2 : std::false_type { };

template<class T, class Alloc>
struct is_vector2<std::vector<T, Alloc>> : std::true_type { };

и каждый из них будет использоваться в разных контекстах

// 1
is_vector1<std::list>::value;

// 2
template<typename C>
auto func(C const& data) -> typename std::enable_if<is_vector2<C>::value>::type
{ /**/ }

Есть ли способ использовать только одну версию в обоих контекстах?

Заметка

У меня нет возможности создать базовый шаблон, вариационный шаблон, я работаю в контексте pre С++ 11

спросил(а) 2015-03-23T13:57:00+03:00 5 лет назад
1
Решение
73

Вы можете решить эту проблему, перегружая функциональные шаблоны:

template<template<class, class> class T>
typename enable_if<!is_vector1<T>::value, char>::type is_vectorf();

template<template<class, class> class T>
typename enable_if<is_vector1<T>::value, char(&)[2]>::type is_vectorf();

template<typename T>
typename enable_if<!is_vector2<T>::value, char>::type is_vectorf();

template<typename T>
typename enable_if<is_vector2<T>::value, char(&)[2]>::type is_vectorf();

После этого просто добавьте простой макрос, который использует sizeof для перевода возвращаемого типа функции:

#define is_vector(T) ::std::integral_constant<bool, sizeof(is_vectorf<T>()) != 1>

Использование довольно очевидно, но может потребоваться typename если оно приводит к зависимому имени. Здесь вы можете увидеть пример.

Обратите внимание, что ::std::enable_if, ::std::integral_constant ::std::declval и ::std::declval - все из стандартной библиотеки С++ 11, но довольно легко имитировать их с помощью С++ 03.

ответил(а) 2015-03-23T16:38:00+03:00 5 лет назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема