将Quadprog++与Eigen一起使用时的C++编译错误



这是我在这里的第一个问题,我已经搜索了很长时间,但没有解决方案。我正在使用QUadprog++来解决一个二次问题。当我单独在测试中使用它时,它还可以。但是,当我在包含Eigen的项目中实现它时,Eigen运算会出现错误,比如"矩阵A没有名为‘lu_inverse’的成员"。如果我注释掉Quadprog++(Array.hh和Quadprog++.hh(的头文件,错误就会消失。所以我认为这是Eigen和Quadprog++的头文件之间的冲突错误。有人知道一些线索吗?提前感谢!

您还可以切换到QuadProgpp版本之一,该版本可以直接使用Eigen类型:https://github.com/asherikov/QuadProgpp,https://www.cs.cmu.edu/~bstephe1/eiquadprog.hpp;或者尝试相同算法的替代实现(也是基于特征的(https://github.com/asherikov/qpmad.

如果您的using namespace quadprogpp;,则不要。您的不同库具有相同的类型名称,这会导致出现错误。键入quadprogpp::someFunction();可能需要更多的字符,但这是值得的。这也是为什么永远不应该在标头中放入using namespace的原因。这是因为您用名称空间符号污染了所有包含该标头的文件,并且可能会导致名称冲突,这与您现在遇到的错误是一样的。

Quadplog库在它自己的命名空间中。

#if !defined(_ARRAY_HH)
#define _ARRAY_HH
#include <set>
#include <stdexcept>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <cstdlib>
namespace quadprogpp {
enum MType { DIAG };
template <typename T>
class Vector

请注意,在#includes之后,命名空间quadprogpp{}被删除,并且在其括起来的方括号中定义的所有内容都将在作用域中定义为quadprogp,因此要使用任何此库,必须在每个内容前面加上命名空间名称。这与使用标准库中的东西没有什么不同。我确信你已经编写了标准的c++hello world

#include<iostream>
int main()
{
std::cout << "hello world!" << std::endl;
return 0;
}

作为命名空间std的一部分的cout和endl必须以std::为前缀才能访问它们。许多c++的新程序员不喜欢这一点,他们搜索的第一件事就是如何不必键入名称空间。

#include<iostream>
using namespace std;
int main()
{
cout << "hello world" << endl;
return 0;
}

新程序员经常做的下一件事是学会将定义放在头文件中,将程序逻辑放在cpp文件中。那是他们犯下一个常见错误的时候。

#ifndef MYHEADER
#define MYHEADER
#include<string>
#include<vector>
#include<iostream>
using namespace std; //Never do this in a header. 

这样做会用标准库中的所有内容污染您的所有代码。这看起来可能是一件微不足道的事情,但当您开始使用另一个库时,或者当您创建自己的类型时,该类型与标准库中的名称相同,会导致名称冲突。

这时编译器根本无法判断您想要哪个Vector。但是Quadprog++中的Quadprog.hh和Array.hh都封装在名称空间quadprogpp中,以专门防止名称冲突,这就是名称空间的全部目的。因此,在您的代码中,可能有一个头文件,您在其中生成了using namespace quadprogpp;的语句,或者其他定义数组类型的命名空间,编译器无法推断您在代码中引用的类型。

除了删除using namespace语句之外,您还可以在typename前面加上其名称空间限定符,以消除您所谈论的类型的歧义。在您的情况下,我相信您的数组应该声明为quadprogpp::Array arraynamme;,而不是简单的Array arrayname;

最新更新