我在头文件transpose
中声明了一个函数global.h
,如下所示:
template <size_t M, size_t N>
extern void transpose(array <array <float, N>, M>&, array <array <float, M>, N>&);
该函数在另一个文件global.cpp
中定义,如下所示:
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];
}
}
}
但是,以下函数调用:
transpose<dim, dim>(jacobian, jacobian_transposed);
抛出错误:
undefined reference to `void transpose<23u, 23u>(std::array<std::array<float, 23u>, 23u>&, std::array<std::array<float, 23u>, 23u>&)'
变量dim
在global.h
中定义,如下所示:
static constexpr const int marker_num = 10;
static constexpr const int dim = (2 * marker_num) + 3;
我找到了this answer。有没有办法将函数定义保留在global.cpp
?
修改:我读了question,此问题被标记为重复。这与@Xirema的答案一起帮助我意识到我有三个选择: 1)在标题中实现功能。
2)使用&#39; .ipp&#39;在文件中实现功能扩展并将其包含在标题内。
3)第三种选择是明确的实例化,如:
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);
以上哪种方法是最好的方法(我正在尝试遵循最佳编码方法)?
答案 0 :(得分:3)
模板定义不能在.cpp文件中实现:需要在标题中。
但是,如果你是一个合理的,合乎逻辑的人,想要将一个函数的声明和定义分成两个不同的文件,你可以使用一种解决方法。
将实现放在文件扩展名的文件中,编译器不会识别(常见的习惯用法是使用.ipp),然后在头文件的末尾添加行#include "impl.ipp"
(或者你使用的任何文件名)。这样可以正确使用模板。