Что происходит во время вывода аргументов шаблона? - PullRequest
0 голосов
/ 17 марта 2019
template <typename T>
// 1:
void compare(T, T) {}

int main{
    compare("123", "45");
}
// T is const char *

// 2:
void compare(T *, T *) {}
// T is const char

// 3:
void compare(const T *, const T *) {}
// T is char

// 4:
void compare(const T, const T) {}
// T is const char *

1

Мой вопрос соответствует схеме 1,2,3, которую я могу полностью понять. почему T становится таким, каким он выглядит. Хотя T в 4-м коде не char *, что я предположил.

2

А почему первый код и 4-й код в результате имеют одинаковый тип T.

3:

Могу ли я использовать reference из const char * в качестве параметра в compare

Ответы [ 3 ]

2 голосов
/ 17 марта 2019

Мой вопрос соответствует шаблону 1,2,3, и я могу полностью понять, почему T становится таким, каким он выглядит. В то время как T в 4-м коде не является символом *, который я предположил.

Потому что вы были введены в заблуждение, узнав неправильный шаблон.Это пример того, почему «ведущий const вводит в заблуждение».Шаблоны не похожи на макросы, и расположение const слева не означает, что оно применимо к char.Это относится ко всему типу параметра, и поскольку параметр будет указателем (из-за литералов, передаваемых в качестве аргументов), синтезированная функция будет выглядеть примерно так:

void compare(char const* const, char const* const) {}

Вот почему многие программисты на C ++ (включая меня) предпочитают другое размещение cv-квалификаторов.Где ваши варианты 3 и 4 были бы написаны так:

void compare(T const *, T const *) {}
// T is char

// 4:
void compare(T const, T const ) {}
// T is const char *

Это более последовательно, потому что const всегда применяется к тому, что слева от него (если есть что-то, в противном случае есть исключение,и запутанное исключение).И это также делает совершенно ясным (ну, в любом случае, IMO), что будет константой, когда вычет закончится.

1 голос
/ 17 марта 2019

Вызов compare получает строковые литералы, типы которых const char *;

1: Мой вопрос соответствует схеме 1,2,3, которую я могу полностью понимаю, почему Т становится таким, как он выглядит. Где Т в 4-й код не символ *, который я предположил.

В const T const относится к T, который равен const char*. Const в const char* относится к символу. Два случая const относятся к разным вещам. С const T x мы не можем изменить x, то есть сам указатель x. С помощью const char* x мы можем изменить указатель, но не символы, на которые указывает x.

2: И почему первый код и 4-й код имеют одинаковый тип Т.

См. Ответ выше. Константа в const T является избыточной для вызывающей стороны. Вызывающей стороне все равно, изменит ли реализация свою копию указателя или нет. Об этом заботится только реализация.

3: Могу ли я использовать ссылку const char * в качестве параметра при сравнении

Конечно, просто напишите const T& или const char*const& (читается справа налево: ссылка на постоянный указатель на символьную константу)

1 голос
/ 17 марта 2019

Принимая во внимание, что T в 4-м коде не является char *, который я предположил.

Обратите внимание, что в 4-м коде const квалифицируется непосредственно для T.Когда T выводится как указатель, тогда const T означает const указатель, а не указатель на const.Таким образом, T выводится как const char*, а аргумент 4-го compare будет const char * const.

Предположим, что T выводится как char *, тогда const T будет char * const (то есть const указатель на не const char), что не являетсяочевидно, ожидаемый тип аргумента.

Могу ли я использовать ссылку const char * в качестве параметра в compare

Я не уверен, что правильно понял ваш вопрос, давы можете написать что-то вроде void compare(const T&, const T&), чтобы изменить его на передачу по ссылке, но также заметьте, что compare("123", "45"); T будет выведено как тип массива (в этом случае вычет на самом деле потерпит неудачу, потому что "123" и"45" не тот же тип массива), распад массива на указатель не произойдет.Возможно, это не то, что вы ожидали.

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