В чем разница между `typename std::remove_reference‹T›` и `constexpr typename std::remove_reference‹T›`?

Согласно документации (https://en.cppreference.com/w/cpp/utility/move), существует два типа конструкторов для std::move<T>, которые описаны ниже.

Чем отличаются эти конструкторы? Что меня больше всего смутило, так это то, почему во втором конструкторе нужно ключевое слово (typename).

Я новичок в С++. Буду признателен за любую подсказку по этому вопросу.

template< class T >
typename std::remove_reference<T>::type&& move( T&& t ) noexcept; (since C++11)(until C++14)

template< class T >
constexpr typename std::remove_reference<T>::type&& move( T&& t ) noexcept;  (since C++14)

person sunshilong369    schedule 28.05.2020    source источник


Ответы (1)


[...] есть два вида конструкторов для std::move<T>...

Нет, это не конструкторы, а сигнатуры функций std::move. Один предшествует c++14(т.е. поскольку c ++11) и второй, начиная с C++14.

Во втором используется спецификатор constexpr, означающий

constexpr — указывает, что значение переменной или функции может появляться в константных выражениях

Подробнее читайте здесь: Для чего полезен constexpr?


Что меня больше всего смутило, так это то, почему во втором конструкторе нужно ключевое слово (typename).

Согласно cppreference.com, для std::remove_reference существует вспомогательный тип, поскольку c++14

template< class T >
using remove_reference_t = typename remove_reference<T>::type;  (since C++14)

поэтому во втором, это могло быть

template< class T >
constexpr std::remove_reference_t<T>&& move( T&& t ) noexcept;
//        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
person JeJo    schedule 28.05.2020
comment
Почему бывшая сигнатура функции не нуждается в ключевом слове typename? Спасибо. - person sunshilong369; 28.05.2020
comment
@sunshilong369 Результирующий тип трейтов std::remove_reference зависит от типа шаблона T, который необходимо указать компилятору с помощью ключевого слова typename. Дополнительные примеры см. здесь: Когда необходимо ключевое слово "typename"? - person JeJo; 28.05.2020
comment
Видите ли, в прежней сигнатуре функции тоже есть std::remove_reference. Так почему же перед ней не нужно ставить typename? - person sunshilong369; 28.05.2020
comment
Извините. Мои глаза обманывают меня. В обоих из них действительно есть ключевые слова. Мое сердце полно благодарности. - person sunshilong369; 28.05.2020