Неопределенная ссылочная ошибка для шаблонного метода [дубликат]

Этот вопрос уже имеет ответ здесь:

Это сводило меня с ума в течение прошлого с половиной часа. Я знаю, что это - мелочь, но не может найти что случилось (то, что это - дождливый день пятницы, конечно, не помогает).

Я определил следующий класс, который будет содержать параметры конфигурации, считанные из файла, и позволит мне получить доступ к ним из своей программы:

class VAConfig {
    friend std::ostream& operator<<( std::ostream& lhs, const VAConfig& rhs);

private:
    VAConfig();
    static std::string      configFilename;
    static VAConfig*        pConfigInstance;
    static TiXmlDocument*   pXmlDoc;
    std::map valueHash;

public:
    static VAConfig* getInstance();
    static void setConfigFileName( std::string& filename ) { configFilename = filename; }
    virtual ~VAConfig();

    void readParameterSet( std::string parameterGroupName );
    template T readParameter( const std::string parameterName );
    template T convert( const std::string& value );
};

где метод convert() определяется в VAConfig.cpp как

template 
T VAConfig::convert( const std::string& value )
{
    T t;
    std::istringstream iss( value, std::istringstream::in );
    iss >> t;
    return t;
}

Все довольно простые. Но когда я тестирую от своего основного использования программы

int y = parameters->convert("5");

Я добираюсь undefined reference to 'int VAConfig::convert...' ошибка компиляции. Так же для readParameter().

Посмотревший много шаблонных учебных руководств, но coul не понимает это. Какие-либо идеи?

43
задан curiousguy 16 August 2012 в 17:15
поделиться

3 ответа

Реализация шаблонного кода никогда не должна быть в файле .cpp : ваш компилятор должен видеть их в то же время, когда он видит код, который их вызывает (если вы не используете явное создание экземпляра для создания шаблонного объектного кода, но даже тогда .cpp - это неправильный тип файла для использования ).

Что вам нужно сделать, так это переместить реализацию либо в файл заголовка, либо в такой файл, как VAConfig.t.hpp , а затем #include "VAConfig.t. hpp " всякий раз, когда вы используете какие-либо шаблонные функции-члены.

69
ответ дан 26 November 2019 в 22:51
поделиться

Шаблонный метод - это просто ... шаблон для метода. Аргументы шаблона должны быть заполнены там, где "создается экземпляр" метода.

Должна быть возможность построить компилятор, который будет удовлетворен объявлением шаблонного метода, и на этапе "компиляции шаблона" скомпилировать все необходимое экземпляры метода шаблона.

Это не относится к vc от Microsoft. Однако я слышал, как один из коллег бормотал насчет того, что это имеет место в unix.

Большинство компиляторов создают экземпляр метода шаблона по запросу, где они используются в исходном коде. Чтобы создать экземпляр метода, компилятор должен «увидеть» тело функции шаблона. Вот почему тело чаще всего помещается либо в файл заголовка, либо, например, в файл .h.cpp, который затем включается в качестве последней строки файла .h.

5
ответ дан 26 November 2019 в 22:51
поделиться

Если вы переместите реализацию шаблонных методов (convert и readParameter) в файл заголовка, она должна работать.

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

10
ответ дан 26 November 2019 в 22:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: