(То, что @jwismar говорит правильно, но это не главная проблема с кодом).
Рассмотрим этот фрагмент кода
void foo(const int*& p);
int main() {
int *p = 0;
foo(p); // ERROR: cannot initialize `const int *&` with `int *`
}
Если вы попытаетесь скомпилировать его,это приведет к ошибке.Причина ошибки в том, что невозможно привязать ссылку типа const int *&
к указателю типа int *
.Это нарушило бы правила правильности.
Другой, меньший пример, который иллюстрирует ту же проблему
int *p = 0;
const int *&rp = p; // ERROR: cannot initialize `const int *&` with `int *`
На самом деле это проблема, с которой вы столкнулись в своем коде.Вы объявили свой шаблон с const TCHAR*&
типом параметра
template <> Log& Log::operator<<( const TCHAR*& input )
{ printf("tchar ptr ref"); }
и ожидаете, что он будет вызван для аргумента TCHAR *
типа
TCHAR* test5 = L"test5";
log << test5;
Это невозможно.Ваш шаблон не считается жизнеспособной функцией для звонка.Либо добавьте const
к типу аргумента, либо удалите const
из типа параметра.Или, может быть, избавиться от ссылки.(Почему вы объявляете параметр как ссылка на указатель?)
PS Может показаться удивительным, что вместо желаемой целевой функции компилятор вызываетtemplate
template <typename T> Log& Log::operator<<( const T& input )
{ printf("ref"); }
На первый взгляд может показаться, что компилятор делает то, что я только что назвал "невозможным".На самом деле то, что делает компилятор, это совсем другое.
Последний шаблон создается с T
, равным TCHAR *
.Как, если вы аккуратно развернете приведенное выше объявление аргумента для T == TCHAR *
, вы получите TCHAR *const &
, а не const TCHAR *&
.Это две совершенно разные вещи.Вполне возможно инициализировать ссылку TCHAR *const &
указателем TCHAR *
, что в точности и делает компилятор в вашем случае.
Возвращаясь к моему простому примеру
int *p = 0;
const int *&rp1 = p; // ERROR: cannot initialize `const int *&` with `int *`
int *const &rp2 = p; // OK, no error here