2014-11-12 3 views
10

Я проверял реализацию clamp в наддува:Что такое «boost :: mpl :: identity <T> :: type» здесь?

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; 
    } 

Если я смотрю на документацию, identity возвращает шаблон аргумент без изменений.

Личность metafunction. Возвращает X без изменений.

И какой смысл использовать его здесь?

Не является typename boost::mpl::identity<T>::type эквивалентом T?

+6

отключает вывод типа по этим параметрам –

+0

, поэтому он вычитает 'T' исключительно на основе первого параметра? aaaah ... thx –

+0

да, точно так же, как вы сказали –

ответ

13

A Вложенное имя-спецификатор создает неконкретизируемый контекст. Поэтому компилятор не будет пытаться вывести тип T на основе второго и третьего параметров, заявленных как:

typename boost::mpl::identity<T>::type const & 

Тип T будет выводиться только на основании типа первого аргумента, а затем используется для создания экземпляра типов от остальных параметров. Использование типа identity является распространенным трюком для предотвращения вычитания типа аргумента шаблона по определенным параметрам, что в противном случае приводило бы к неоднозначной ошибке вызова в случае различения типов аргументов, но использует параметр шаблона того же типа. Иногда также может потребоваться не допустить, чтобы компилятор автоматически выводил тип, и принудительно вызывал вызывающий абонент сделать это сам.

+0

Есть ли еще кто-нибудь, чтобы достичь того же результата? (Вне того, как я предполагаю, написать другую функцию и отличить 'lo' и' hi') – Barry

+1

@Barry, несомненно, потому что существуют аналогичные способы создания не выводимого контекста. Тем не менее, немногие из них будут такими же элегантными и идиоматическими, как это. Итак, зачем вам это по-другому? (Если вам не нравится MPL, просто напишите мета-функцию 'identity' самостоятельно. Это все ~ 6 строк кода) – sehe

+4

+1 Один nitpick: вы можете упомянуть, что использование вложенного' :: type' в неопределенный контекст допускает неявные преобразования на 'hi' и' lo', которые не учитываются при выводе аргумента. Разрешение таких смешанных типов параметров будет основным приложением здесь. – TemplateRex

Смежные вопросы