Я не понимаю, как в этом случае работает правило вывода аргументов. У меня есть следующий простой фрагмент кода:
template<typename T>
void fn(T const &&t) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
std::cout << typeid(decltype(t)).name() << std::endl;
}
int main() {
int const *ar = nullptr;
std::cout << typeid(ar).name() << std::endl;
fn(std::move(ar));
}
Результат, который я получаю, выглядит следующим образом:
PKi
void fn(const T &&) [T = const int *]
PKi
Чего я не понимаю, так это почему T
выводится как const int *
. Почему const
не совпало с шаблоном?
const
в параметре шаблона const T&&
и в const int *
. Я ожидал, что T
станет int *
, а не const int *
.
void fn(T const* &&t)
дает то, что вы ожидали?
Но const int*
!= int* const
.
Я думаю, что они @Evg
Нет, это разные виды.
возможно, вы имеете в виду, что int const *
и int * const
— это разные типы.
@Amir int const *
и const int *
одинаковы, const int *
и int * const
разные, размещение const
до или после *
имеет значение.
Короткий доклад, который может показаться вам интересным: youtube.com/watch?v=fv--IKZFVO8
В объявлении параметра T const &&t
, const
квалифицируется на T
, т. е. t
объявляется как rvalue-ссылка на const T
.
Когда передается ar
с типом const int *
, T
выводится как const int *
, тогда тип t
будет const int * const &&
, то есть rvalue-ссылка на const
указатель на const int
. Обратите внимание, что const
квалифицируются по разным вещам (на разных уровнях), один для указателя, другой для указателя.
Спасибо за ответ. Почему T
выводится как const int *
. Наверное я не так понимаю typeid
. Фрагмент показывает, что тип t
такой же, как и тип ar
, и нет дополнительной константы.
@Amir Да, для typeid
, Если type является ссылочным типом, результат ссылается на объект std::type_info, представляющий ссылочный тип.Во всех случаях квалификаторы cv верхнего уровня игнорируются идентификатором типа.
@Amir В результате typeid(const int*) == typeid(const int * const &&)
это true
.
какой
const
не совпал?