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>&)'

变量dimglobal.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"(或您使用的任何文件名)。这将使模板的正确使用成为可能。