Вопрос по templates, linker, compilation, c++ – Неопределенная ссылочная ошибка для метода шаблона [дубликат]

43

This question already has an answer here:

Why can templates only be implemented in the header file? 15 answers

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

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

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<std::string, std::string> valueHash;

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

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

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

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

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

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

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

Посмотрел много шаблонных уроков, но не могу понять это. Есть идеи?

Полтора часа не так уж и плохо ... вчера убили меня на 3. Keith Pinson

Ваш Ответ

3   ответа
5

должны быть заполнены в том случае, если метод «создан».

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

Это не относится к Майкрософт vc. Я слышал, как бормотал коллега об этом в случае с Unix.

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

@greyfade: Спасибо!
.h.cpp или .hpp?
То, что вы описываете, является "внешним шаблоном". Он включен в следующую версию стандарта C ++ и поддерживается GCC в течение длительного времени (как расширение). Visual C ++ должен поддерживать его в текущей бета-версии следующего выпуска.
67

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

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

Вы ответили в 2009 году и помогли мне через 9 лет, спасибо :)
При создании его экземпляра компилятору необходимо иметь полное определение шаблона, чтобы он мог подставить параметры шаблона и оценить его. Если ваш компилятор поддерживает это, вы можете объявить свой шаблон как & quot; extern & quot; и использовать его так же, как любой другой участник, за счет дополнительной работы в режиме связывания. GCC поддерживает это как расширение. Это будет частью стандарта C ++ 0x.
Благодаря Сету и Доминику, я переместил реализации в заголовочный файл, и это сработало. Я никогда не видел, чтобы этот аспект упоминался ни в одном учебнике, который я прочитал. Итак, почему компилятор должен видеть реализацию в то же время, когда он видит код, который их вызывает, то есть что делает шаблонные функции уникальными в этом отношении? recipriversexclusion
Существуют методы, позволяющие не использовать шаблоны, а именно: объявить о специализации шаблонов. -1 для & quot; никогда не должен & quot;
10

ter) в файл заголовка, это должно сработать.

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

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