Невыведенный контекст, такой как «boost::mpl::identity‹T›::type» в стандартной библиотеке?

Рассмотрим следующий пример, который я откопал здесь, в StackOverflow.

  template<typename T, typename Pred> 
  T const & clamp ( T const& val, 
    typename boost::mpl::identity<T>::type const & lo, 
    typename boost::mpl::identity<T>::type const & hi, Pred p )
  {
//    assert ( !p ( hi, lo ));    // Can't assert p ( lo, hi ) b/c they might be equal
    return p ( val, lo ) ? lo : p ( hi, val ) ? hi : val;
  } 

где typename boost::mpl::identity<T>::type не позволяет компилятору вывести T на основе типа второго и третьего аргумента. Это очень удобно для меня, но я не могу использовать Boost Library (пожалуйста, не ругайте меня из-за этого, так как из-за этого уже тяжело).

Теперь вопрос в том, есть ли что-то эквивалентное в стандартной библиотеке, чего я просто не могу найти?


person user32434999    schedule 08.09.2018    source источник
comment
если в стандарте ничего нет, реализовать это самостоятельно не составит труда: файл сводка здесь — почти все, что нужно   -  person kmdreko    schedule 09.09.2018
comment
@kmdreko Совершенно верно. Я просто подумал о том, есть ли он в библиотеке, потому что мне показалось, что это хорошая вещь.   -  person user32434999    schedule 09.09.2018


Ответы (3)


C++20 будет иметь std::type_identity. Но на самом деле вам не нужно ждать, пока она появится в стандартной библиотеке. Вся его реализация:

template< class T >
struct type_identity {
    using type = T;
};

template< class T >
using type_identity_t = typename type_identity<T>::type;
person Barry    schedule 09.09.2018

boost::mpl::identity — довольно прямолинейный пересылать шаблон, который предоставляет только type, идентичный предоставленному параметру шаблона.

Это может быть реализовано следующим образом:

template <typename X>
struct identity
{
    typedef X type;
};
person kmdreko    schedule 09.09.2018

std::common_type_t<T> работает. Из cppreference:

Если sizeof...(T) равно единице (т. е. T... содержит только один тип T0), тип-член именует тот же тип, что и std::common_type<T0, T0>::type, если он существует; в противном случае тип члена отсутствует.

Таким образом, std::common_type_t будет работать для этого

person Justin    schedule 09.09.2018
comment
Не то, чтобы я обязательно рекомендовал это. Не очевидно, что он делает это - person Justin; 09.09.2018