Undefined reference error for template method [duplicate]

To pytanie ma już odpowiedź tutaj:

To doprowadza mnie do szału przez ostatnie półtorej godziny. Wiem, że to mała rzecz, ale nie mogę znaleźć tego, co jest nie tak (fakt, że jest deszczowe Piątkowe popołudnie, oczywiście, nie pomaga).

Zdefiniowałem następująca klasa, która przechowuje parametry konfiguracyjne odczytane z pliku i pozwoli mi uzyskać do nich dostęp z mojego programu:

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 );
};

Gdzie Metoda convert() jest zdefiniowana w VAConfig.cpp jako

template <typename T>
T VAConfig::convert( const std::string& value )
{
    T t;
    std::istringstream iss( value, std::istringstream::in );
    iss >> t;
    return t;
}
Wszystko całkiem proste. Ale kiedy testuję z mojego głównego programu używając
int y = parameters->convert<int>("5");

Dostaję undefined reference to 'int VAConfig::convert<int>...' błąd kompilacji. Ditto dla readParameter().

Spojrzałem na wiele samouczków szablonów, ale nie mogłem tego rozgryźć. Jakieś pomysły?

Author: curiousguy, 2009-07-10

3 answers

Implementacja kodu szablonowego nigdy nie powinna znajdować się w pliku .cpp: Twój kompilator musi widzieć je w tym samym czasie, co kod, który je wywołuje (chyba że użyjesz jawnej instancji do wygenerowania kodu szablonowego, ale nawet wtedy {[0] } jest złym typem pliku do użycia).

To, co musisz zrobić, to przenieść implementację do pliku nagłówkowego lub do pliku, takiego jak VAConfig.t.hpp, a następnie #include "VAConfig.t.hpp" za każdym razem, gdy używasz dowolnych szablonowych funkcji składowych.

 64
Author: Seth Johnson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-24 11:41:59

Jeśli przeniesiesz implementację metod szablonowych (convert i readParameter) do pliku nagłówkowego, powinno działać.

Kompilator musi mieć dostęp do implementacji szablonowych funkcji w miejscach, w których są tworzone.

 9
Author: dma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-10 19:17:05

Metoda szablonowa jest tylko a ... szablon dla metody. Argumenty szablonu należy wypełnić tam, gdzie metoda jest "instancjowana".

Powinno być możliwe zbudowanie kompilatora, który jest zgodny z deklaracją metody szablonowej, A krok "kompilacji szablonu" kompiluje wszystkie potrzebne instancje metody szablonowej.

Tak nie jest w przypadku vc Microsoftu. Słyszałem mruczenie kolegi o tym, że tak jest na Unixie.

Najbardziej Kompilatory tworzą instancje metody szablonowej na żądanie, gdzie są one używane w kodzie źródłowym. Aby utworzyć instancję metody, kompilator musi "zobaczyć" ciało funkcji szablonu. Dlatego ciało jest najczęściej umieszczane albo w pliku nagłówkowym, albo np. w a .h.cpp pliku, który następnie jest dołączany jako ostatnia linia .plik H.

 5
Author: xtofl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-10 19:33:59