Почему мне разрешено явно создавать экземпляр специализации шаблона, где аргумент по умолчанию неявно не преобразуется в другой тип? - PullRequest
0 голосов
/ 14 января 2019

См. Следующий код:

#include <iostream>

template<typename T = int>
void func(T t = 1)
{
    std::cout << t << std::endl;
}

template void func<int>(int); // Explicit instantion of `int`
template void func<std::string>(std::string); // Explicit instantiation of `std::string` -- why does this not give the same error as below?

int main()
{
    func(); // Outputs "1" - OK
    func(std::string("test")); // Outputs "test" - OK
    // func<std::string>(); // Explicit instantiation - Fails (as expected!): could not convert '1' from 'int' to 'std::string'
}

Я бы подумал, что строка template void func<std::string>(std::string); будет недопустимой, поскольку аргумент int по умолчанию не может быть неявно преобразован в std::string (аналогично тому, как я получаю ошибку компиляции при последнем вызове), и что мне придется прибегнуть к решению, изложенному в этом ответе .

Когда у меня есть шаблон функции с аргументом по умолчанию, почему мне разрешено явно создавать экземпляр специализации шаблона, где аргумент по умолчанию неявно не преобразуется в другой тип? Это оказывается именно тем, что Я хотел, но мне любопытно узнать, как компилятор все выясняет.

1 Ответ

0 голосов
/ 14 января 2019

Параметр шаблона по умолчанию и его значение по умолчанию указываются для шаблона функции func, что означает, что они учитываются только в том случае, если шаблон не создан с каким-либо типом и значением.

Так что func(std::string("test")); call использует явное создание шаблона с std::string и завершается успешно.

Принимая во внимание, что func<std::string>(); потерпит неудачу, потому что используется явное создание шаблона с std::string, но значение параметра по умолчанию - 1 (что является int).

Это эквивалентно:

func<std::string>(1);

И компилятор (GCC 8.2) сообщает об одинаковой ошибке для обоих этих вызовов.

<source>:18:23: note:   cannot convert '1' (type 'int') to type 'std::__cxx11::basic_string<char>'

См. Демо здесь .

...