Clang ++ fait échouer l'éditeur de liens sur les classes de modèles (mais cela fonctionne avec g ++)
J'ai un programme qui fonctionne bien avec GCC, mais le compiler avec Clang fait échouer l'éditeur de liens.
Je pense que mon problème concerne les classes de modèles, j'ai donc implémenté ce petit exemple.
test.cpp
:
#include "Point.h"
int main()
{
Point<int> p1;
Point<int> p2{ 3, 6 };
}
Point.h
:
#ifndef POINT_H
#define POINT_H
template<typename T>
class Point {
T x, y;
public:
Point();
Point(T, T);
};
template class Point<int>;
template class Point<float>;
#endif
Point.cpp
:
#include "Point.h"
template<typename T>
Point<T>::Point()
: x{0}, y{0}
{}
template<typename T>
Point<T>::Point(T t_x, T t_y)
: x{t_x}, y{t_y}
{}
Quand je le construis avec g++ Point.cpp test.cpp
, cela fonctionne sans problème.
Mais avec Clang, cela donne les erreurs suivantes:
$ clang++ Point.cpp test.cpp
/usr/bin/ld: /tmp/test-8ab886.o: in function `main':
test.cpp:(.text+0x1a): undefined reference to `Point<int>::Point()'
/usr/bin/ld: test.cpp:(.text+0x2d): undefined reference to `Point<int>::Point(int, int)'
clang-11: error: linker command failed with exit code 1 (use -v to see invocation)
Ou, en utilisant lld:
$ clang++ -fuse-ld=lld Point.cpp test.cpp
ld.lld: error: undefined symbol: Point<int>::Point()
>>> referenced by test.cpp
>>> /tmp/test-f95759.o:(main)
ld.lld: error: undefined symbol: Point<int>::Point(int, int)
>>> referenced by test.cpp
>>> /tmp/test-f95759.o:(main)
clang-11: error: linker command failed with exit code 1 (use -v to see invocation)
Je suppose que mes instanciations explicites dans Point.h
ne sont pas assez bonnes pour Clang, mais je ne peux pas comprendre ce qu'il veut.
Réponses
Votre instanciation explicite doit être là où les définitions sont visibles, donc à la fin de Points.cpp
De class_template # Explicit_instantiation :
Une définition d'instanciation explicite force l'instanciation de la classe, de la structure ou de l'union à laquelle elle fait référence. Il peut apparaître dans le programme n'importe où après la définition du modèle, et pour une liste d'arguments donnée, il n'est autorisé à apparaître qu'une fois dans l'ensemble du programme, aucun diagnostic n'est requis.