Шаблонный оператор << явная реализация и заголовок - PullRequest
0 голосов
/ 18 июня 2009

Обычно для моих шаблонных классов я включаю объявления в файл .hpp и шаблонный код реализации в файл .t.hpp. Я явно создаю экземпляр класса в .cpp файле:

template class MyClass< AnotherClass >;

чей объектный код помещается в библиотеку.

Проблема в том, что если я пытаюсь напечатать объект с operator<<, который объявлен в файле .hpp и определен в файле .t.hpp как:

template<class T>
std::ostream& operator<<( std::ostream& os, const MyClass<T>& c)
{
    os  << "Hello, I am being output.";
    return os;
}

Я получаю ошибку компоновщика о том, что правильный символ не определен.

Я понимаю, что это потому, что эта шаблонная функция явно не создается, когда класс. Есть ли способ обойти это, кроме как включить файл .t.hpp всякий раз, когда я хочу использовать operator<< в классе, или переместить шаблонный код функции в файл .hpp? Можно ли явно создать экземпляр кода функции?

Ответы [ 2 ]

2 голосов
/ 18 июня 2009

См. Решение Литба .

В вашем конкретном случае компилятор может вывести все аргументы шаблона из параметров и возвращаемых типов, но если это невозможно, вы можете указать их явно:

template std::ostream& operator<< <T>(std::ostream&, const MyClass<T>&);

Это все еще разрешено, если аргументы шаблона могут быть выведены.

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

2 голосов
/ 18 июня 2009

Вы можете явно создавать экземпляры шаблонов функций

template std::ostream& operator<<(std::ostream&, const MyClass<int>&);

Для создания специализации с T = int. Скобки аргументов шаблона могут быть опущены, если все аргументы шаблона могут быть выведены (как в этом случае, из типа MyClass<int>. Если это невозможно, например, потому что параметры шаблона не встречаются в типе параметра функции, у вас есть явно указать его

template<typename T> void f() { }
template void f<int>();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...