c++ - 使用带有 std::vector 和特征矩阵的模板时,来自 GCC 的未定义引用错误?

标签 c++ templates stdvector eigen

使用 GCC 编译以下代码时遇到 undefined reference 错误 4.7.2 x86_64-suse-linux下的20130108通过命令:

g++ main.cpp func.cpp -I/path/to/eigenlibrary/eigen_3.2.1

错误消息如下:

     main.cpp:(.text+0x1d): undefined reference to `void f<2>(std::vector<Eigen::Matrix<double, 2, 2, 
((Eigen::._84)0)|((((2)==(1))&&((2)!=(1)))?
    ((Eigen::._84)1) : ((((2)==(1))&&((2)!=(1)))?((Eigen::._84)0) : ((Eigen::._84)0))), 2, 2>,
     std::allocator<Eigen::Matrix<double, 2, 2, ((Eigen::._84)0)|((((2)==(1))&&((2)!=(1)))?
    ((Eigen::._84)1) : ((((2)==(1))&&((2)!=(1)))?((Eigen::._84)0) : ((Eigen::._84)0))), 2, 2> > >&)'

请注意,这与模板实现与头文件分离的事实无关,因为模板函数没有(通用)实现,而只有模板专门化。模板特化的实现不能放入头文件中,因为这会产生多个定义错误。

这里的另一个奇怪的事情是,如果我更改 main.cpp 中前两个 header 包含的顺序(特征/密集和 vector ),则不会发生错误。我对此一无所知,任何超出“简单地更改 header 包含内容的顺序”的帮助都将受到高度赞赏。

main.cpp:

#include <vector>
#include <Eigen/Dense>

//error does not occur once I change order of header inclusion like so:
//#include <Eigen/Dense>
//#include <vector>

#include "func.h"

int main() {
    std::vector<Eigen::Matrix<double, 2, 2> > m;  
    f<2>(m);
}

func.h

#ifndef FUNC_H
#define FUNC_H

#include <Eigen/Dense>
#include <vector>

template <int N>
void f(std::vector<Eigen::Matrix<double, N, N> >& m);

template <> void f<2>(std::vector<Eigen::Matrix<double, 2, 2> >& m);

#endif 

func.cpp

#include "func.h"
#include <vector>

template <>
void f<2>(std::vector<Eigen::Matrix<double, 2, 2> >& m) {} 

最佳答案

func.h 中,您的模板特化声明应为:

template <> void f<2>(std::vector<Eigen::Matrix<double, 2, 2> >& m);

因此,整个过程中都填写了 N=2,就像您对 func.cpp 中的定义所做的那样。

请注意,如果您将 inline 添加到定义中,您应该能够在 func.h 中定义模板特化。


我可以使用 GCC 4.6.4、4.7.4、4.8.2、4.9.0 重现该故障,但不能使用 Clang 3.4.2(全部在 Arch Linux 上):

$ echo $'func.h\n---'; cat func.h; echo $'---\nfunc.c++\n---'; cat func.c++; echo $'---\nmain.c++\n---'; cat main.c++; g++-4.6 -I/usr/include/eigen3 main.c++ func.c++; ./a.out
func.h
---
#ifndef FUNC_H
#define FUNC_H

#include <Eigen/Dense>
#include <vector>

template <int N>
void f(std::vector<Eigen::Matrix<double, N, N> >& m);

template <> void f<2>(std::vector<Eigen::Matrix<double, 2, 2> >& m);

#endif
---
func.c++
---
#include "func.h"
#include <vector>

template <>
void f<2>(std::vector<Eigen::Matrix<double, 2, 2> >& m) {}
---
main.c++
---
#include <vector>
#include <Eigen/Dense>

//error does not occur once I change order of header inclusion like so:
//#include <Eigen/Dense>
//#include <vector>

#include "func.h"

int main() {
    std::vector<Eigen::Matrix<double, 2, 2> > m;  
    f<2>(m);
}

我强烈建议就此事联系 Eigen 开发人员。

关于c++ - 使用带有 std::vector 和特征矩阵的模板时,来自 GCC 的未定义引用错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24730981/

相关文章:

c++ - 类模板 C++ 中的虚方法模板

c++ - C++ 中字符的标准字符串行为

c++ - 如何将类成员函数的返回类型设置为私有(private)结构的对象

c++ - std::begin 的 SFINAE 问题

C++ 派生类型必须定义静态 constexpr

c++ - std::vector 默认构造函数可以抛出异常吗

C++:在 map 中插入 vector

C++,boost asio,慢读

c++ - 特化模板<typename T, template<typename> class U>

c++ - 如何从 vector 中删除所有元素