Explicit instantiation of template template method
От: ezdoctor  
Дата: 02.03.18 17:57
Оценка:
Не удается явно инстанциировать шаблонный метод шаблонного класса. Буду благодарен, если подскажете, что не так.

Имеем заголовочный файл с определением шаблонного класса, где методы всего лишь объявлены, но не определены:
//header.h
template<typename T>
class C {
public:
    void memberFunction();

    template <typename S>
    void templateMemberFunction();
};


Как видим, объявлены два метода, один обычный нестатический метод, другой метод шаблонный.
Далее, есть файл, где данный класс и оба его метода используются. Иными словами, класс инстанциируется типом T=int, а его шаблонный метод вдобавок типом S=double:
//main.cpp
#include<header.h>

...
    C<int> c;
    c.memberFunction();
    c.templateMemberFunction<double>();


Определение самих методов "спрятано" в другом файле:
//class_implementation.cpp
#include<header.h>

template<>
void C<int>::memberFunction() {
}

template <>
template <>
void C<int>::templateMemberFunction<double>() {
}

На самом деле это даже не определение, а специализация шаблонных методов определенными типами. Если построить проект на этом этапе, то оба метода не будут найдены линкером, потому что информация о том, какими именно типами инстанциируются класс и метод в файле main.cpp, отсутствует в процессе компиляции class_implementation.cpp. Для решения этой проблемы требуется инстанциировать класс нужными нам типами в файле class_implementation.cpp. Например, так:
//class_implementation.cpp
void this_function_is_not_used_anywhere() {
    C<int> c;
    c.memberFunction();
    c.templateMemberFunction<double>();
}

То есть определяем функцию, которая нигде не используется (и потому линкером будет выброшена), которая использует нужный нам класс и его методы, инстанциируя нужными типами. Как следствие, в объектном файле class_implementation.o содержатся определения всех нужных методов, и линкер находит все необходимое для сборки проекта. Проблема в том, что инстанциирование методом this_function_is_not_used_anywhere есть кривизна, которой хочется избежать. И этого удается избежать для memberFunction явной инстанциацией:
//class_implementation.cpp
template void C<int>::memberFunction();

Или даже лучше так (инстанциируем не метод, а весь класс):
//class_implementation.cpp
template class C<int>;

Но вот для шаблонного метода templateMemberFunction сделать по аналогии у меня не выходит. Следующий код компилируется, но линкер все равно не находит нужного определения метода:
//class_implementation.cpp
template void C<int>::templateMemberFunction<double>();


Данный код написан на коленке, выброшено все, лишь бы проиллюстрировать идею, так что не обращайте внимание на возможные синтактические ошибки. Важно следующее: не удается сделать явную инстанциацию шаблонного метода шаблонного класса, при том, что просто метод этого шаблонного класса инстанциируется без проблем. Компилятор VS2013. Есть ли идеи по поводу того, что здесь не так?
explicit instantiation
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.