使用 valuePtr() 等为 Eigen3 SparseMatrix 分配 space
Using valuePtr() etc to allocate space for Eigen3 SparseMatrix
我正在尝试通过使用 malloc
来初始化 Eigen::SparseMatrix A
A.valuePtr() = static_cast<T*>(std::malloc(nnz*sizeof(T)));
A.innerIndexPtr() = static_cast<int*>(std::malloc(nnz*sizeof(int)));
但我收到错误
error: lvalue required as left operand of assignment
对于这两个语句。以防万一,包含这些行的函数通过引用采用 Eigen::SparseMatrix<T, Eigen::RowMajor>
。
谁能帮我解决这个问题?我正在使用 g++ 5.2。
编辑:
classSparseMatrix
的函数valuePtr
是
inline Scalar* valuePtr() { return &m_data.value(0); }
Scalar
是模板参数。 m_data
是类型 CompressedStorage
的受保护变量,其方法 value(size_t i)
returns 对其内部数据数组的第 i 个成员的 引用 。
inline Scalar& value(size_t i) { return m_values[i]; }
所以,我得出的结论是valuePtr()
returns数组首元素的地址。那么,我应该能够通过 malloc 为该数组分配 space。
如果有人感兴趣,我附上一个 link 供参考 - 请参阅 84 和 131 之后的行。Eigen3 SparseMatrix class
问题很可能是由于您试图将对象分配给方法!
你的行等同于:
A.valuePtr() = Sometype_Pointer;
, A.valuePTR()
会调用对象A的Eigen::SparseMatrix::valuePTR
方法(函数).
如果此方法 return 是一个指针 (T* A::valuePtr()
),那么 returned 指针不是您想要的!该方法将是 returning a rvalue; rvalue 不是 A 中包含的指针的 lvalue,而是 临时副本 的指针。
你不能直接给它分配任何东西,就像你不能触摸电视屏幕上的人一样。
我假设您正在尝试执行我上面描述的操作,除非该方法看起来像这样,否则这是不可能的:
T ** Eigen::SparseMatrix::valuePTR()
{
return &T;
}
*A.valuePtr() = static_cast<T*>(std::malloc(nnz*sizeof(T)));
但是,请注意使用 malloc 对于 c++ 对象来说被认为是非常非常过时的,类似这行的东西会更 正确
*A.valuePtr() = static_cast(新 T[nnz]));
[编辑/]
老实说,我非常努力地了解您的代码应该完成什么。大多数人(包括我自己)都不会熟悉这个 "Eigen" class。虽然我认为您可能非常误解它应该如何使用。
您能否提供一个 link 文档,或者您如何创建/使用此 class 的示例?
[编辑 2/]
经过一番研究,我发现了 This article as well as This Question, could it be possible you need to use a MappedSparseMatrix
[编辑 3/]
inline Scalar* valuePtr() { return &m_data.value(0); }
将 return 一个 rvalue 指针。这不是 m_data 中保存的对象,也不是内部使用的指针。它是指向现有对象的指针的临时副本,试图说"make this temporary copy point to something else"没有意义。
inline Scalar& value(size_t i) { return m_values[i]; }
在这种情况下,方法 return 是对对象 的引用 ,引用不是指针 - (尽管 &
经常让人感到困惑)。
一个引用可以理解为原始对象,不需要解引用一个引用。考虑以下因素。
int A;
int * A_p = &A;
int & A_r = A;
int & A_r_2 = *A_p;
//de-reference the pointer (to create a reference)
*A_p = 10; //A == 10
//Assign directly to A (via the reference)
A_r = 12; // A == 12
//assign directy to A (via the reference to A, that was taken from A_p
A_r_2 = 15; // A == 15
//attempt to de-reference a reference
*A_r = 10; //ERROR, A_r is not a pointer.
简而言之,被return编辑的引用不是指向对象(已经存在)的指针,而是对象。这将允许您将对象设置为某物,或使用 .
运算符调用对象上的方法,但是您不能重新分配已经存在的东西,因此是错误的。
请考虑阅读这篇关于 C++ 中右值和左值的区别的文章 understanding rvalue and lvalue
在@John Bargman 告诉我我对右值和左值的看法是错误的之后,我想了想并尝试了这个:
class A
{
char* str;
public:
// This function returns a literal (constant) of type char*
// (just an address), not a pointer variable
char* getstr() {
return str;
}
char getchar(const int i) const {
return str[i];
}
};
int main()
{
A a;
// the RHS can't be assigned to a literal, we need a variable in the LHS
a.getstr() = static_cast<char*>(malloc(10*sizeof(char))); // ILLEGAL!
// this assigns the address contained in str to mstr.
char* mstr = a.getstr();
// after this, mstr will have nothing to do with A::str; the former
// will have been re-assigned to a different address
mstr = static_cast<char*>(malloc(10*sizeof(char)));
for(int i = 0; i < 9; i++)
mstr[i] = '0';
mstr[9] = '[=10=]';
// The following line segfaults as no storage has been allocated to A::str
cout << a.getchar(1) << endl; // runtime error!
free(mstr);
return 0;
}
现在我明白函数 SparseMatrix::valuePtr()
和 A::getstr()
一样,return 是某种地址类型的文字;它不是 return 左值。尝试将某些内容(在本例中,内存块的起始地址 return 由 malloc
编辑)分配给文字(在本例中,某些地址,如 0x233ff554)是没有意义的。我想我现在明白它是如何工作的了。谢谢@John Bargman!
我正在尝试通过使用 malloc
来初始化 Eigen::SparseMatrix A
A.valuePtr() = static_cast<T*>(std::malloc(nnz*sizeof(T)));
A.innerIndexPtr() = static_cast<int*>(std::malloc(nnz*sizeof(int)));
但我收到错误
error: lvalue required as left operand of assignment
对于这两个语句。以防万一,包含这些行的函数通过引用采用 Eigen::SparseMatrix<T, Eigen::RowMajor>
。
谁能帮我解决这个问题?我正在使用 g++ 5.2。
编辑:
classSparseMatrix
的函数valuePtr
是
inline Scalar* valuePtr() { return &m_data.value(0); }
Scalar
是模板参数。 m_data
是类型 CompressedStorage
的受保护变量,其方法 value(size_t i)
returns 对其内部数据数组的第 i 个成员的 引用 。
inline Scalar& value(size_t i) { return m_values[i]; }
所以,我得出的结论是valuePtr()
returns数组首元素的地址。那么,我应该能够通过 malloc 为该数组分配 space。
如果有人感兴趣,我附上一个 link 供参考 - 请参阅 84 和 131 之后的行。Eigen3 SparseMatrix class
问题很可能是由于您试图将对象分配给方法!
你的行等同于:
A.valuePtr() = Sometype_Pointer;
, A.valuePTR()
会调用对象A的Eigen::SparseMatrix::valuePTR
方法(函数).
如果此方法 return 是一个指针 (T* A::valuePtr()
),那么 returned 指针不是您想要的!该方法将是 returning a rvalue; rvalue 不是 A 中包含的指针的 lvalue,而是 临时副本 的指针。
你不能直接给它分配任何东西,就像你不能触摸电视屏幕上的人一样。
我假设您正在尝试执行我上面描述的操作,除非该方法看起来像这样,否则这是不可能的:
T ** Eigen::SparseMatrix::valuePTR()
{
return &T;
}
*A.valuePtr() = static_cast<T*>(std::malloc(nnz*sizeof(T)));
但是,请注意使用 malloc 对于 c++ 对象来说被认为是非常非常过时的,类似这行的东西会更 正确 *A.valuePtr() = static_cast(新 T[nnz]));
[编辑/]
老实说,我非常努力地了解您的代码应该完成什么。大多数人(包括我自己)都不会熟悉这个 "Eigen" class。虽然我认为您可能非常误解它应该如何使用。
您能否提供一个 link 文档,或者您如何创建/使用此 class 的示例?
[编辑 2/]
经过一番研究,我发现了 This article as well as This Question, could it be possible you need to use a MappedSparseMatrix
[编辑 3/]
inline Scalar* valuePtr() { return &m_data.value(0); }
将 return 一个 rvalue 指针。这不是 m_data 中保存的对象,也不是内部使用的指针。它是指向现有对象的指针的临时副本,试图说"make this temporary copy point to something else"没有意义。
inline Scalar& value(size_t i) { return m_values[i]; }
在这种情况下,方法 return 是对对象 的引用 ,引用不是指针 - (尽管 &
经常让人感到困惑)。
一个引用可以理解为原始对象,不需要解引用一个引用。考虑以下因素。
int A;
int * A_p = &A;
int & A_r = A;
int & A_r_2 = *A_p;
//de-reference the pointer (to create a reference)
*A_p = 10; //A == 10
//Assign directly to A (via the reference)
A_r = 12; // A == 12
//assign directy to A (via the reference to A, that was taken from A_p
A_r_2 = 15; // A == 15
//attempt to de-reference a reference
*A_r = 10; //ERROR, A_r is not a pointer.
简而言之,被return编辑的引用不是指向对象(已经存在)的指针,而是对象。这将允许您将对象设置为某物,或使用 .
运算符调用对象上的方法,但是您不能重新分配已经存在的东西,因此是错误的。
请考虑阅读这篇关于 C++ 中右值和左值的区别的文章 understanding rvalue and lvalue
在@John Bargman 告诉我我对右值和左值的看法是错误的之后,我想了想并尝试了这个:
class A
{
char* str;
public:
// This function returns a literal (constant) of type char*
// (just an address), not a pointer variable
char* getstr() {
return str;
}
char getchar(const int i) const {
return str[i];
}
};
int main()
{
A a;
// the RHS can't be assigned to a literal, we need a variable in the LHS
a.getstr() = static_cast<char*>(malloc(10*sizeof(char))); // ILLEGAL!
// this assigns the address contained in str to mstr.
char* mstr = a.getstr();
// after this, mstr will have nothing to do with A::str; the former
// will have been re-assigned to a different address
mstr = static_cast<char*>(malloc(10*sizeof(char)));
for(int i = 0; i < 9; i++)
mstr[i] = '0';
mstr[9] = '[=10=]';
// The following line segfaults as no storage has been allocated to A::str
cout << a.getchar(1) << endl; // runtime error!
free(mstr);
return 0;
}
现在我明白函数 SparseMatrix::valuePtr()
和 A::getstr()
一样,return 是某种地址类型的文字;它不是 return 左值。尝试将某些内容(在本例中,内存块的起始地址 return 由 malloc
编辑)分配给文字(在本例中,某些地址,如 0x233ff554)是没有意义的。我想我现在明白它是如何工作的了。谢谢@John Bargman!