J'ai une fonction transpose
déclarée dans un fichier d'en-tête global.h
comme indiqué ci-dessous:C++ - Erreur « référence non définie » tout en utilisant des modèles avec fonction
template <size_t M, size_t N>
extern void transpose(array <array <float, N>, M>&, array <array <float, M>, N>&);
La fonction est définie dans un autre fichier global.cpp
comme indiqué ci-dessous:
template <size_t M, size_t N>
void transpose(array <array <float, N>, M>& a, array <array <float, M>, N>& b)
{
// This can be made faster
for (size_t i = 0; i < M; i++)
{
for (size_t j = 0; j < N; j++)
{
b[j][i] = a[i][j];
}
}
}
Cependant, l'appel de fonction suivante:
transpose<dim, dim>(jacobian, jacobian_transposed);
jette l'erreur:
undefined reference to `void transpose<23u, 23u>(std::array<std::array<float, 23u>, 23u>&, std::array<std::array<float, 23u>, 23u>&)'
Le dim
variable est définie à l'global.h
comme indiqué ci-dessous:
static constexpr const int marker_num = 10;
static constexpr const int dim = (2 * marker_num) + 3;
je trouve this answer. Existe-t-il des moyens de conserver la définition de la fonction dans le global.cpp
?
Modifier: J'ai lu le question dont cette question a été marquée comme doublon. Cela avec la réponse de @Xirema m'a aidé à réaliser que j'ai trois options: 1) Implémenter la fonction dans l'en-tête.
2) Implémenter la fonction dans un fichier avec l'extension '.ipp' et l'inclure dans l'en-tête.
3) La troisième option est instanciation explicite comme:
template <size_t M, size_t N>
void transpose(array <array <float, N>, M>& a, array <array <float, M>, N>& b)
{
// This can be made faster
for (size_t i = 0; i < M; i++)
{
for (size_t j = 0; j < N; j++)
{
b[j][i] = a[i][j];
}
}
}
template void transpose(array <array <float, dim>, dim>& a, array <array <float, dim>, dim>& b);
template void transpose(array <array <float, dim>, 2>& a, array <array <float, 2>, dim>& b);
Lequel de ce qui précède est la meilleure méthode (je suis en train de suivre les meilleures pratiques de codage)?
Est-ce une mauvaise pratique de déplacer l'implémentation vers l'en-tête? De plus, si j'ai un fichier avec l'extension '.ipp' cela fonctionnera-t-il avec tous les compilateurs? Est-ce mieux que la méthode du fichier d'en-tête? –
@skr_robo Ils n'ont pas besoin d'être dans un en-tête, mais si vous voulez partager l'implémentation entre plusieurs fichiers, l'implémentation doit être visible pour tous les utilisateurs. Un compilateur C++ ne se soucie pas de ce que vous nommez le fichier d'implémentation. Lorsqu'il repère une instruction '# include ', il recherche le fichier et le colle effectivement dans le fichier en cours de compilation. Vous pouvez inclure n'importe quel fichier syntaxiquement correct, y compris des astuces abusives qui chargent un fichier csv depuis Excel ou Matlab dans un tableau. Vous pouvez '# inclure 'des fichiers syntaxiquement incorrects si vous le souhaitez, mais le compilateur l'étouffera plus tard. – user4581301
Okay. J'essaie de voir lequel est l'approche la plus professionnelle. S'il vous plaît voir la modification. –