Шаблонная специализация с типами cv и ref - PullRequest
0 голосов
/ 03 февраля 2019

Чтобы понять метапрограммирование, я создал простой пример:

template <class T> struct add_cref      { typedef T const& type; };
// template <class T> struct add_cref<T&>   { typedef T const& type; };


std::cout << std::boolalpha
    << std::is_same<add_cref<int>::type, int const&>::value << std::endl
    << std::is_same<add_cref<int&>::type, int const&>::value << std::endl
    << std::is_same<add_cref<const int>::type, int const&>::value << std::endl
    << std::is_same<add_cref<int const&>::type, int const&>::value << std::endl;

Результат: true, false, true, true
Когда я раскомментирую спецификацию шаблона,результат, как и ожидалось (все верно)

Мой вопрос: почему второй ложный, а последний истинный без специализации, когда оба используют специализацию, когда она не закомментирована.

1 Ответ

0 голосов
/ 03 февраля 2019
template <class T> 
struct add_cref { 
    typedef T const& type; 
};

С типом add_cref<int&>::type, T = int&.Тип add_cref<int&>::type тогда примерно такой же, как int& const &, что означает, что ссылка int& является константой, а не целым числом.

Редактировать: С типом add_cref<const int&>::type, T = const int&.Тип add_cref<const int&>::type тогда примерно такой же, как const int& const &, что означает, что сама ссылка const int& является const (второе const игнорируется компилятором), но относится к const int.Это означает, что add_cref<const int&>::type должно быть const int&, даже без специализации.

Со специализацией:

template <class T> 
struct add_cref<T&> { 
   typedef T const& type; 
}; 

Для add_cref<int&>, поскольку в этой специализации T&=int&, затем T=int.В результате type из T const& становится int const &.

...