当与 header 个文件一起使用时,使用个人 C++ 库编译代码会中断
Compiling code using personal C++ library breaks when used in conjunction with header files
我有一些跨项目使用的 C++ 实用函数。
我想用这些实用程序制作一个库来为项目提供服务,而不必 copy/paste 我可能做出的任何更改。
我可以将单个 .cpp 文件转换为库:
$ g++ -c util.cpp
$ ar rcs libutil.a util.o
并制作了一个具有所有功能的 util.h header。
这个库用于编译和 运行 一个简单的 test.cpp,它使用库函数打印一个点和向量的平均值:(我将 header 移动到 ~ /.local/include/ 和库到 ~/.local/lib/)
$ g++ -o test test.cpp -L ~/.local/lib/ -lutil
$ ./test
.
4.5
但是,当我尝试使用该库编译(部分)项目时,出现“{function} 未在此范围内声明”错误。
$ g++ -c source/linreg.cpp -L ~/.local/lib/ -lutil
...
linreg.cpp:11:18: error: ‘vecMean’ was not declared in this scope
...
试图重现我写的这个行为:
// header.h
#ifndef HEADER_H
#define HEADER_H
void test();
#endif
// main.cpp
#include "header.h"
#include "util.h"
int main()
{
dot();
test();
return 0;
}
// test.cpp
#include <string>
#include <vector>
#include <iostream>
#include "util.h"
#include "header.h"
void test()
{
dot();
std::vector<double> x;
for(int i = 0; i < 10; ++i)
x.push_back(i * 1.0);
std::cout << vecMean(x) << std::endl;
}
不编译。
取决于哪个 #includes 在另一个之前,
抛出不同的错误。
以上抛出“'dot' 未在此范围内声明”,
而下面的抛出“'test' 未在此范围内声明”
// main.cpp
#include "util.h"
#include "header.h"
...
这与我在尝试编译实际项目时看到的行为相同。
如果我从 main.cpp 中删除 dot() 调用,示例编译并且 运行 没问题,除非将 util.h include 语句放在 header.h 之前(虽然我猜 util.h 包含是没有意义的)。这导致 'test' 未被声明。
我觉得我遗漏了一些明显的东西,
尽管整个学习建立图书馆的过程都很艰难。
看到 header 文件似乎是问题的一部分,我在下面添加我的 util.h,
以及 util.cpp,以备不时之需。
#ifndef HEADER_H
#define HEADER_H
#include <vector>
#include <tuple>
#include <fstream>
#include <string>
/***** utils *****/
// smallest/largest value from a vector
int indexSmallest(const std::vector<double> &vec);
int indexLargest(const std::vector<double> &vec);
// some vector operations
std::vector<double> sclMult(const std::vector<double> &vec, double scl);
std::vector<double> sclAdd(const std::vector<double> &vec, double scl);
std::vector<double> vecAdd(const std::vector<double> &vec1, const std::vector<double> &vec2);
std::vector<double> vecSub(const std::vector<double> &vec1, const std::vector<double> &vec2);
std::vector<std::vector<double> > vecCat(const std::vector<double> &vec1,
const std::vector<double> &vec2,
const std::vector<double> &vec3);
double vecMean(const std::vector<double> &vec);
double vecSum(const std::vector<double> &vec);
// sort two vectors of length 3 by the elements in the err vector
std::tuple<std::vector<std::vector<double> >, std::vector<double> >
sort(const std::vector<std::vector<double> > &X, const std::vector<double> &err);
// return maximum and minimum values from vector
std::vector<double> topbot(std::vector<double> &vec);
// print a dot
void dot(std::string str = ".");
// print a vector of doubles
void printVec(std::vector<double> vec);
// print a matrix of doubles
void printMat(std::vector<std::vector<double> > mat);
#endif
#include <vector>
#include <tuple>
#include <cmath>
#include <iostream>
#include <string>
#include "util.h"
int indexSmallest(const std::vector<double> &vec)
{
int index = 0;
for(int i = 1; i < vec.size(); i++)
{
if(vec[i] < vec[index])
index = i;
}
return index;
}
int indexLargest(const std::vector<double> &vec)
{
int index = 0;
for(int i = 1; i < vec.size(); i++)
{
if(vec[i] > vec[index])
index = i;
}
return index;
}
std::vector<double> sclMult(const std::vector<double> &vec, double scl)
{
std::vector<double> vvec(vec.size());
for(int i = 0; i < vec.size(); i++){
vvec[i] = vec[i] * scl;
}
//printVec(vvec);
return vvec;
}
std::vector<double> sclAdd(const std::vector<double> &vec, double scl)
{
std::vector<double> vvec(vec.size());
for(int i = 0; i < vec.size(); i++)
vvec[i] = vec[i] + scl;
return vvec;
}
std::vector<double> vecAdd(const std::vector<double> &vec1, const std::vector<double> &vec2)
{
std::vector<double> vvec(vec1.size());
//std::cout << "aaaa ";
//printVec(vec1);
for(int i = 0; i < vec1.size(); i++){
vvec[i] = (vec1[i] + vec2[i]);
}
return vvec;
}
std::vector<double> vecSub(const std::vector<double> &vec1, const std::vector<double> &vec2)
{
std::vector<double> vvec(vec1.size());
for(int i = 0; i < vec1.size(); i++)
vvec[i] = (vec1[i] - vec2[i]);
//vvec.push_back(vec1[i] - vec2[i]);
return vvec;
}
std::vector<std::vector<double> > vecCat(const std::vector<double> &vec1,
const std::vector<double> &vec2,
const std::vector<double> &vec3)
{
std::vector<std::vector<double> > vecCat(3);
vecCat[0] = vec1;
vecCat[1] = vec2;
vecCat[2] = vec3;
return vecCat;
}
std::tuple<std::vector<std::vector<double> >, std::vector<double> >
sort(const std::vector<std::vector<double> > &X, const std::vector<double> &err)
{
//std::cout << X.size() << ' ' << err.size() << std::endl;
std::vector<double> sortErr(3);
//std::vector<std::vector<double> > sortX;
int small = indexSmallest(err), large = indexLargest(err);
if(small == large)
return std::make_tuple(X,err);
int middle = fabs(small + large - 3);
//std::cout << small << ' ' << middle << ' ' << large << std::endl;
sortErr[0] = err[small];
sortErr[1] = err[middle];
sortErr[2] = err[large];
std::vector<std::vector<double> > sortX = vecCat(X[small],X[middle],X[large]);
/* sortX[0] = X[small];
sortX[1] = X[middle];
sortX[2] = X[large];*/
return std::make_tuple(sortX,sortErr);
}
double vecMean(const std::vector<double> &vec)
{
double sum = 0;
for(int i = 0;i < vec.size();i++){
sum += vec[i];
}
return sum / vec.size();
}
double vecSum(const std::vector<double> &vec)
{
double sum = 0;
for(int i = 0;i < vec.size();i++){
sum += vec[i];
}
return sum;
}
void dot(std::string str)
{
std::cout << str << std::endl;
}
std::vector<double> topbot(std::vector<double> &vec)
{
double top = vec[0];
double bot = vec[0];
for(int i = 1; i < vec.size(); ++i){
if(vec[i] > top)
top = vec[i];
if(vec[i] < bot)
bot = vec[i];
}
std::vector<double> topbot = {top,bot};
return topbot;
}
void printVec(std::vector<double> vec)
{
for(int i = 0; i < vec.size(); ++i){
std::cout << vec[i] << ',';
}
std::cout << std::endl;
}
void printMat(std::vector<std::vector<double> > mat)
{
for(int i = 0; i < mat.size(); ++i){
printVec(mat[i]);
}
}
std::vector<double> head(std::vector<double> vec, int n)
{
std::vector<double> head;
for(int i = 0; i < n; ++i)
head.push_back(vec[i]);
return head;
}
std::vector<double> tail(std::vector<double> vec, int n)
{
std::vector<double> tail;
for(int i = vec.size() - n; i < vec.size(); ++i)
tail.push_back(vec[i]);
return tail;
}
std::vector<double> normalize(std::vector<double> vec)
{
std::vector<double> tb = topbot(vec);
std::vector<double> norm;
for(int i = 0; i < vec.size(); ++i)
norm.push_back((vec[i] - tb[1]) / (tb[0] - tb[1]));
return norm;
}
std::vector<double> vecLog(std::vector<double> vec)
{
std::vector<double> logged;
for(int i = 0; i < vec.size(); ++i)
logged.push_back(std::log(vec[i]));
return logged;
}
std::vector<double> vecExp(std::vector<double> vec)
{
std::vector<double> logged;
for(int i = 0; i < vec.size(); ++i)
logged.push_back(std::exp(vec[i]));
return logged;
}
问题是你在两个 headers:
中都有相同的 include guard
#ifndef HEADER_H
#define HEADER_H
因此两个文件之一——此处为 util.h
——被跳过,因为该符号实际上已经被定义。
根据经验,我是否也可以建议您为库命名一些更独特的东西——比如 verkutil——并带有一个包含保护来匹配?我的经验是太多项目有自己的 UTIL_H
符号和类似命名的文件。
我有一些跨项目使用的 C++ 实用函数。 我想用这些实用程序制作一个库来为项目提供服务,而不必 copy/paste 我可能做出的任何更改。
我可以将单个 .cpp 文件转换为库:
$ g++ -c util.cpp
$ ar rcs libutil.a util.o
并制作了一个具有所有功能的 util.h header。
这个库用于编译和 运行 一个简单的 test.cpp,它使用库函数打印一个点和向量的平均值:(我将 header 移动到 ~ /.local/include/ 和库到 ~/.local/lib/)
$ g++ -o test test.cpp -L ~/.local/lib/ -lutil
$ ./test
.
4.5
但是,当我尝试使用该库编译(部分)项目时,出现“{function} 未在此范围内声明”错误。
$ g++ -c source/linreg.cpp -L ~/.local/lib/ -lutil
...
linreg.cpp:11:18: error: ‘vecMean’ was not declared in this scope
...
试图重现我写的这个行为:
// header.h
#ifndef HEADER_H
#define HEADER_H
void test();
#endif
// main.cpp
#include "header.h"
#include "util.h"
int main()
{
dot();
test();
return 0;
}
// test.cpp
#include <string>
#include <vector>
#include <iostream>
#include "util.h"
#include "header.h"
void test()
{
dot();
std::vector<double> x;
for(int i = 0; i < 10; ++i)
x.push_back(i * 1.0);
std::cout << vecMean(x) << std::endl;
}
不编译。 取决于哪个 #includes 在另一个之前, 抛出不同的错误。
以上抛出“'dot' 未在此范围内声明”, 而下面的抛出“'test' 未在此范围内声明”
// main.cpp
#include "util.h"
#include "header.h"
...
这与我在尝试编译实际项目时看到的行为相同。
如果我从 main.cpp 中删除 dot() 调用,示例编译并且 运行 没问题,除非将 util.h include 语句放在 header.h 之前(虽然我猜 util.h 包含是没有意义的)。这导致 'test' 未被声明。
我觉得我遗漏了一些明显的东西, 尽管整个学习建立图书馆的过程都很艰难。
看到 header 文件似乎是问题的一部分,我在下面添加我的 util.h, 以及 util.cpp,以备不时之需。
#ifndef HEADER_H
#define HEADER_H
#include <vector>
#include <tuple>
#include <fstream>
#include <string>
/***** utils *****/
// smallest/largest value from a vector
int indexSmallest(const std::vector<double> &vec);
int indexLargest(const std::vector<double> &vec);
// some vector operations
std::vector<double> sclMult(const std::vector<double> &vec, double scl);
std::vector<double> sclAdd(const std::vector<double> &vec, double scl);
std::vector<double> vecAdd(const std::vector<double> &vec1, const std::vector<double> &vec2);
std::vector<double> vecSub(const std::vector<double> &vec1, const std::vector<double> &vec2);
std::vector<std::vector<double> > vecCat(const std::vector<double> &vec1,
const std::vector<double> &vec2,
const std::vector<double> &vec3);
double vecMean(const std::vector<double> &vec);
double vecSum(const std::vector<double> &vec);
// sort two vectors of length 3 by the elements in the err vector
std::tuple<std::vector<std::vector<double> >, std::vector<double> >
sort(const std::vector<std::vector<double> > &X, const std::vector<double> &err);
// return maximum and minimum values from vector
std::vector<double> topbot(std::vector<double> &vec);
// print a dot
void dot(std::string str = ".");
// print a vector of doubles
void printVec(std::vector<double> vec);
// print a matrix of doubles
void printMat(std::vector<std::vector<double> > mat);
#endif
#include <vector>
#include <tuple>
#include <cmath>
#include <iostream>
#include <string>
#include "util.h"
int indexSmallest(const std::vector<double> &vec)
{
int index = 0;
for(int i = 1; i < vec.size(); i++)
{
if(vec[i] < vec[index])
index = i;
}
return index;
}
int indexLargest(const std::vector<double> &vec)
{
int index = 0;
for(int i = 1; i < vec.size(); i++)
{
if(vec[i] > vec[index])
index = i;
}
return index;
}
std::vector<double> sclMult(const std::vector<double> &vec, double scl)
{
std::vector<double> vvec(vec.size());
for(int i = 0; i < vec.size(); i++){
vvec[i] = vec[i] * scl;
}
//printVec(vvec);
return vvec;
}
std::vector<double> sclAdd(const std::vector<double> &vec, double scl)
{
std::vector<double> vvec(vec.size());
for(int i = 0; i < vec.size(); i++)
vvec[i] = vec[i] + scl;
return vvec;
}
std::vector<double> vecAdd(const std::vector<double> &vec1, const std::vector<double> &vec2)
{
std::vector<double> vvec(vec1.size());
//std::cout << "aaaa ";
//printVec(vec1);
for(int i = 0; i < vec1.size(); i++){
vvec[i] = (vec1[i] + vec2[i]);
}
return vvec;
}
std::vector<double> vecSub(const std::vector<double> &vec1, const std::vector<double> &vec2)
{
std::vector<double> vvec(vec1.size());
for(int i = 0; i < vec1.size(); i++)
vvec[i] = (vec1[i] - vec2[i]);
//vvec.push_back(vec1[i] - vec2[i]);
return vvec;
}
std::vector<std::vector<double> > vecCat(const std::vector<double> &vec1,
const std::vector<double> &vec2,
const std::vector<double> &vec3)
{
std::vector<std::vector<double> > vecCat(3);
vecCat[0] = vec1;
vecCat[1] = vec2;
vecCat[2] = vec3;
return vecCat;
}
std::tuple<std::vector<std::vector<double> >, std::vector<double> >
sort(const std::vector<std::vector<double> > &X, const std::vector<double> &err)
{
//std::cout << X.size() << ' ' << err.size() << std::endl;
std::vector<double> sortErr(3);
//std::vector<std::vector<double> > sortX;
int small = indexSmallest(err), large = indexLargest(err);
if(small == large)
return std::make_tuple(X,err);
int middle = fabs(small + large - 3);
//std::cout << small << ' ' << middle << ' ' << large << std::endl;
sortErr[0] = err[small];
sortErr[1] = err[middle];
sortErr[2] = err[large];
std::vector<std::vector<double> > sortX = vecCat(X[small],X[middle],X[large]);
/* sortX[0] = X[small];
sortX[1] = X[middle];
sortX[2] = X[large];*/
return std::make_tuple(sortX,sortErr);
}
double vecMean(const std::vector<double> &vec)
{
double sum = 0;
for(int i = 0;i < vec.size();i++){
sum += vec[i];
}
return sum / vec.size();
}
double vecSum(const std::vector<double> &vec)
{
double sum = 0;
for(int i = 0;i < vec.size();i++){
sum += vec[i];
}
return sum;
}
void dot(std::string str)
{
std::cout << str << std::endl;
}
std::vector<double> topbot(std::vector<double> &vec)
{
double top = vec[0];
double bot = vec[0];
for(int i = 1; i < vec.size(); ++i){
if(vec[i] > top)
top = vec[i];
if(vec[i] < bot)
bot = vec[i];
}
std::vector<double> topbot = {top,bot};
return topbot;
}
void printVec(std::vector<double> vec)
{
for(int i = 0; i < vec.size(); ++i){
std::cout << vec[i] << ',';
}
std::cout << std::endl;
}
void printMat(std::vector<std::vector<double> > mat)
{
for(int i = 0; i < mat.size(); ++i){
printVec(mat[i]);
}
}
std::vector<double> head(std::vector<double> vec, int n)
{
std::vector<double> head;
for(int i = 0; i < n; ++i)
head.push_back(vec[i]);
return head;
}
std::vector<double> tail(std::vector<double> vec, int n)
{
std::vector<double> tail;
for(int i = vec.size() - n; i < vec.size(); ++i)
tail.push_back(vec[i]);
return tail;
}
std::vector<double> normalize(std::vector<double> vec)
{
std::vector<double> tb = topbot(vec);
std::vector<double> norm;
for(int i = 0; i < vec.size(); ++i)
norm.push_back((vec[i] - tb[1]) / (tb[0] - tb[1]));
return norm;
}
std::vector<double> vecLog(std::vector<double> vec)
{
std::vector<double> logged;
for(int i = 0; i < vec.size(); ++i)
logged.push_back(std::log(vec[i]));
return logged;
}
std::vector<double> vecExp(std::vector<double> vec)
{
std::vector<double> logged;
for(int i = 0; i < vec.size(); ++i)
logged.push_back(std::exp(vec[i]));
return logged;
}
问题是你在两个 headers:
中都有相同的 include guard#ifndef HEADER_H
#define HEADER_H
因此两个文件之一——此处为 util.h
——被跳过,因为该符号实际上已经被定义。
根据经验,我是否也可以建议您为库命名一些更独特的东西——比如 verkutil——并带有一个包含保护来匹配?我的经验是太多项目有自己的 UTIL_H
符号和类似命名的文件。