специализация класса шаблона enable_if и значения по умолчанию - PullRequest
0 голосов
/ 06 июня 2018

Учитывая следующее

template <typename T, typename Enable=void>
struct test{};

template <typename T,
    typename std::enable_if< some_trait<T>::value >::type >
struct test{};

при условии, что some_trait<T>::value равно true, enable_if<T>::type равно void, и специализация выбрана.Тем не менее, мой запрос связан с выбором, когда имеет место следующее.

template <typename T,
    typename std::enable_if_t< some_trait<T>::value,T>::type >
struct test{};

Когда для enable_if предусмотрен второй параметр шаблона void, для ::type выбирается неспециализированный шаблон, дажекогда some_trait<T>::value равно true, а ::type равно T вместо void, и поэтому не соответствует значению по умолчанию в основном шаблоне.

Мой вопрос - где в стандартеописан порядок, для которого выбран шаблон, и почему экземпляр test<T,void> считается лучшим соответствием, чем test<T,T>.

https://ideone.com/7v4TTS

полный образец:

#include <iostream>
#include <type_traits>

template <typename T,typename Enable=void>
struct test
{
    const char* value = "Primary";
};

#if 1// toggle this

template <typename T>
struct test<T,typename std::enable_if< std::is_same<T,T>::value >::type > 
{
    const char* value = "Specialization";
};

#else

template <typename T>                                    
struct test<T,typename std::enable_if< std::is_same<T,T>::value,T >::type> 
{                                                          ///  ^    
    const char* value = "Specialization";
};

#endif

int main() {
    test<int> v;
    std::cout << v.value << std::endl;
    return 0;
}

Ответы [ 3 ]

0 голосов
/ 06 июня 2018

У меня вопрос, где в стандарте описан порядок, для которого выбран шаблон, и почему экземпляр test<T,void> считается лучшим соответствием, чем test<T,T>.

[temp.class.spec.match] .

Вы написали test<int>, что означает, что вы не указали аргумент шаблона для второго параметра.Поскольку он имеет параметр по умолчанию, он выбран, поэтому у вас фактически есть test<int, void>.

Теперь, согласно тексту, связанному выше, параметры шаблона соответствуют специализации.

InВ первом случае специализация test<int, void> после оценки, и поэтому она является точным совпадением и выбрана.

Во втором случае специализация test<int, int> после оценки, которая не является точным совпадением ипоэтому вместо этой специализации выбран основной шаблон.

0 голосов
/ 06 июня 2018

test<int> v; равно test<int, void> v; (благодаря типу по умолчанию).

test<int, int> v; выберет вашу последнюю специализацию.

0 голосов
/ 06 июня 2018

В первом случае у вас есть тип

std::enable_if< true, void >

Во втором случае у вас есть тип

std::enable_if< true, int >

std::enable_if< true, int >::type равен int.Он не квалифицируется как тип для typename Enable, который был запрошен как void

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...