C++ - 将模板与函数一起使用时出错 'undefined reference'
C++ - Error 'undefined reference' while using templates with function
我在 header 文件 global.h
中声明了一个函数 transpose
,如下所示:
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) 在header.
中实现函数
2) 在扩展名为“.ipp”的文件中实现函数并将其包含在 header.
中
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);
以上哪个是最好的方法(我正在尝试遵循最佳编码实践)?
模板定义不能在 .cpp 文件中实现:它需要在header.
但是,如果您是一个通情达理、有逻辑的人,想要将函数的声明和定义分开到两个不同的文件中,可以使用 work-around。
将实现放在一个文件扩展名编译器无法识别的文件中(一个常见的习惯用法是使用 .ipp),然后在 header 文件的末尾添加行 #include "impl.ipp"
(或您使用的任何文件名)。这将使模板的正确使用成为可能。
我在 header 文件 global.h
中声明了一个函数 transpose
,如下所示:
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) 在header.
中实现函数2) 在扩展名为“.ipp”的文件中实现函数并将其包含在 header.
中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);
以上哪个是最好的方法(我正在尝试遵循最佳编码实践)?
模板定义不能在 .cpp 文件中实现:它需要在header.
但是,如果您是一个通情达理、有逻辑的人,想要将函数的声明和定义分开到两个不同的文件中,可以使用 work-around。
将实现放在一个文件扩展名编译器无法识别的文件中(一个常见的习惯用法是使用 .ipp),然后在 header 文件的末尾添加行 #include "impl.ipp"
(或您使用的任何文件名)。这将使模板的正确使用成为可能。