使用Eigen库读取文件时遇未定义引用错误,求问题排查
问题分析与解决
你遇到的链接错误核心原因是函数声明和定义的参数签名不匹配:
- 你在
main函数前声明的ReadFromTextFile,第一个参数是值传递的Eigen::MatrixXf:void ReadFromTextFile(Eigen ::MatrixXf, const char*); - 但实际实现的函数,第一个参数是引用传递的
Eigen::MatrixXf &:void ReadFromTextFile(Eigen ::MatrixXf &matrix ,const char *filename) { ... }
在C++中,函数的传递方式(值/引用)属于函数签名的一部分,编译器会把这两个视为完全不同的函数。所以当main里调用声明版本的函数时,链接器找不到对应的实现,就会抛出undefined reference错误。
修正步骤
统一函数声明与定义的参数,把声明改成引用传递(这样还能避免矩阵拷贝的性能开销):
void ReadFromTextFile(Eigen::MatrixXf&, const char*);另外代码里还有一个小问题:
matrix.array().resize(rows,cols);写法不正确,Eigen的动态矩阵MatrixXf可以直接调用resize()方法,不需要通过array():matrix.resize(rows, cols);
修正后的完整代码
#include <iostream> #include <math.h> #include <complex.h> #include <vector> #include <algorithm> #include <iterator> #include <fstream> #include <eigen3/Eigen/Dense> #include <eigen3/Eigen/Core> using namespace Eigen; using namespace std; using Eigen::MatrixXf; // 修正后的函数声明:参数为引用 void ReadFromTextFile(Eigen::MatrixXf&, const char*); int main() { MatrixXf x; ReadFromTextFile(x,"data.txt"); cout << "Rows: " << x.rows() << " Cols: " << x.cols() << endl; } void ReadFromTextFile(Eigen::MatrixXf &matrix ,const char *filename) { std::ifstream inFile (filename,std::ios::in); if(!inFile.good()) { std::cout<<"Error: could not open file:\""<<filename<<"\"for reading \n"; exit (2); } // 统计文件中数值的数量 std::istream_iterator<std::string> in{inFile}; std::istream_iterator<std::string> end; long numberofWords=std::distance(in,end); // 统计文件行数 inFile.clear(); inFile.seekg(0,std::ios::beg); long numberofLines=std::count(std::istreambuf_iterator<char>(inFile),std::istreambuf_iterator<char>(),'\n'); std::cout<<"no. of words : "<<numberofWords<<" numberofLines: "<<numberofLines<<std::endl; long rows=numberofLines; long cols=numberofWords/numberofLines; if(rows*cols!=numberofWords) { std::cout<<"\n Infile "<<filename<<" cannot form a matrix \n"; exit(2); } // 修正resize写法 matrix.resize(rows,cols); inFile.clear(); inFile.seekg(0,std::ios::beg); for(unsigned int i=0;i<matrix.rows();i++) for(unsigned int j=0;j<matrix.cols();j++) inFile>>matrix(i,j); inFile.close(); }
编译验证
现在用你原来的编译命令就能正常通过了:
g++ file.cpp -o file -lm -std=c++11
内容的提问来源于stack exchange,提问作者Ema
相关产品推荐
相关产品推荐

