C ++ - 错误'未定义的引用'同时使用带功能的模板

时间:2017-04-16 18:46:58

标签: c++ function templates global

我在头文件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>&)'

变量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)在标题中实现功能。

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);

以上哪种方法是最好的方法(我正在尝试遵循最佳编码方法)?

1 个答案:

答案 0 :(得分:3)

模板定义不能在.cpp文件中实现:需要在标题中。

但是,如果你是一个合理的,合乎逻辑的人,想要将一个函数的声明和定义分成两个不同的文件,你可以使用一种解决方法。

将实现放在文件扩展名的文件中,编译器不会识别(常见的习惯用法是使用.ipp),然后在头文件的末尾添加行#include "impl.ipp" (或者你使用的任何文件名)。这样可以正确使用模板。