специализация шаблона со ссылкой на const - PullRequest
2 голосов
/ 11 апреля 2019

Я пытаюсь понять, как работают шаблонные специализации.У меня есть следующий шаблон функции:

template <typename T>
void function(const T &t1, const T &t2)
{
    std::cout << "in function template: " << t1 << ", " << t2 << std::endl;
}

Теперь я хочу специализировать этот шаблон функции в случае, если он вызывается с указателем на const:

// template specialization
template <>
void function(const char *&t1, const char *&t2)
{
    std::cout << "in compare template specialization: " << t1 << ", " << t2 << std::endl;
}

, но компилятор жалуетсячто он не может найти шаблон функции для специализации:

In file included from main.cpp:1:0:
template.h:23:5: error: template-id 'compare<>' for 'int compare(const char*&, const char*&)' does not match any template declaration
 int compare(const char *&t1, const char *&t2)
     ^~~~~~~
template.h:10:5: note: candidate is: template<class T> int compare(const T&, const T&)
 int compare(const T &t1, const T &t2)

, если я специализирую шаблон следующим образом (ссылка на указатель CONST на const), он работает:

// template specialization
template <>
int compare(const char * const &t1, const char * const &t2)  // now the pointer itself is const
{
    std::cout << "in compare template specialization: " << t1 << ", " << t2 << std::endl;
}

Я хочу вызвать функцию с const char *Ptr = "hello world", поэтому я подумал, что выводимый параметр T был char *, а параметр const char * &.

Не является ли const в списке параметров шаблона функции всегда низкимуровень const?

1 Ответ

4 голосов
/ 11 апреля 2019

Шаблоны не являются простым механизмом замены токенов, как макросы.const T здесь не означает "вставьте меня туда, где T сразу после const".Это означает, что тип вещи "const независимо от того, что T есть".В случае шаблона вашей функции, если вы установите T равным const char*, тогда тип const T& будет ссылкой на const независимо от того, чем является T, то есть ссылкой на const char*, которыйсамо по себе const, т. е. const char * const &.Это на самом деле ничем не отличается от того, что если T было именем, определенным с помощью typedef, а не параметром шаблона, например:

using T = int*;
const T blub = 42;  // type of blub is int* const, not const int*

Следовательно,

template <>
void function(const char*& t1, const char*& t2);

не является действительной специализациейшаблон функции function.Нет T, который вы могли бы заменить в своем шаблоне function, чтобы получить эту подпись.Если вы замените const char* на параметр T, т. Е. На форму function<const char*>, его подпись будет иметь вид

void function<const char*>(const char * const& t1, const char * const& t2);

Обратите внимание, что вместо того, чтобы полагаться на явную специализацию, если вы хотите отдельнуюфункция для обработки случая

void function(const char*& t1, const char*& t2);

, просто добавьте такую ​​функцию и полагайтесь на перегрузку, чтобы творить ее магию.В общем, когда вы пишете явную специализацию шаблонов функций, есть вероятность, что вы на самом деле хотели просто использовать перегрузку.См. Также Шаблон специализации VS Перегрузка функций или в этой статье (старая, но все еще такая же, как и прежде), чтобы узнать больше об этом ...

...