2017-01-18 3 views
3

В типа, как в неспециализированной шаблона структуры pointer_traits (т.е. template <class Ptr> struct pointer_traits), существует шаблон rebind псевдоним элемент, который определен, чтобы быть Ptr::rebind<U>, если она существует, или какой-либо другой тип в противном случае. Хотя я видел несколько ответов на , проверив, существует ли какой-то элемент, как реализовать шаблон условного шаблона, например pointer_traits::rebind? То есть, как если бы следующий псевдо-C++:«Условные» шаблоны псевдонимов

template <typename T> using type = has_type<T::U> ? int : float; 

или

template <typename T> using type = if_has_type<T::U, int, float>::type; 

Я рассматривал что-то вроде способа, изображенного на https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Member_Detector (раздел «Обнаружение типов элементов»), но я не» t знать, как реализовать вспомогательную структуру, чей тип члена [sole] зависит от существования другого типа элемента.

ответ

4

Используя std::conditional от <type_traits>. Это так же просто, как:

using type = typename std::conditional<bool, int, float>::type; 

или

using type = std::conditional_t<bool, int, float>; 

где вы замените bool с некоторым условием, оцениваемым во время компиляции к логическому значению. В этом случае условием является проверка существующего элемента.

Если состояние true, то он становится псевдонимом int, в противном случае - float.

ПОЛНЫЙ ПРИМЕР (Проверьте, если difference_type является типом членом.)

namespace detail { 

template<class Ptr> 
using ptrait_diff = typename Ptr::difference_type; 

template<class Ptr, bool = is_detected<ptrait_diff, Ptr>::value> 
struct ptrait_diff_t { 
    using type = ptrdiff_t; 
}; 

template<class Ptr> 
struct ptrait_diff_t<Ptr, true> { 
    using type = typename Ptr::difference_type; 
}; 

} // namespace detail 

, а затем:

template<class Ptr> 
struct pointer_traits 
{ 
    using difference_type = typename detail::ptrait_diff_t<Ptr>::type; 
}; 

Осуществление is_detected можно найти HERE.

+0

Я думаю, цит больше интересует, как условие будет выглядеть, а не станд :: условной – WorldSEnder

+0

Реализация 'станд :: conditional' кажется легко понять, но как' is_detected' работа? Кроме того, хотя я являюсь поклонником новых возможностей C++ 17, «pointer_traits» был реализован на C++ 11. Не используя [экспериментальные] возможности C++ 17, как реализовать это? –

+0

@AliciaRose * Без использования [экспериментальных] возможностей C++ 17, как бы реализовать это? * Уродливо и мучительно. Вы можете найти исходный код для своей стандартной библиотеки в Интернете. – DeiDei

2

В этом проблема std::conditional предназначена для решения проблемы.

#include <type_traits> 
template<bool condition> 
using type = std::conditional_t<condition, int, float>; 

static_assert(std::is_same<type<true>, int>::value, "type<true> should be int"); 
static_assert(std::is_same<type<false>, float>::value, "type<false> should be float"); 
Смежные вопросы