我正在尝试使用Eigen::SparseMatrix A
这样的<{p}}来初始化malloc
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。
编辑:
类valuePtr
的函数SparseMatrix
是
inline Scalar* valuePtr() { return &m_data.value(0); }
Scalar
是模板参数。 m_data
是CompressedStorage
类型的受保护变量,其方法value(size_t i)
会将引用返回给其内部数据数组的第i个成员。
inline Scalar& value(size_t i) { return m_values[i]; }
因此,我得出结论valuePtr()
返回数组第一个元素的地址。那么,我应该能够通过malloc为该数组分配空间。
如果有人感兴趣,我会提供一个参考链接 - 请参阅84和131之后的行。Eigen3 SparseMatrix class
答案 0 :(得分:1)
问题很可能是由于您尝试将对象分配给方法!
你的行等于:
A.valuePtr() = Sometype_Pointer;
,A.valuePTR()
将调用对象A的Eigen::SparseMatrix::valuePTR
方法(函数)。
如果此方法返回指针(T* A::valuePtr()
),则返回的指针不是您想要的!该方法将返回 rvalue ; rvalue 不是左值,它不是A中包含的指针,而是指针的临时副本。
您无法直接向其指定任何内容,就像您无法在电视屏幕上触摸人一样。
我正在做一个大量的假设,即你试图做我上面描述的事情,除非那个方法看起来像这样,否则这是不可能的:
T ** Eigen::SparseMatrix::valuePTR()
{
return &T;
}
*A.valuePtr() = static_cast<T*>(std::malloc(nnz*sizeof(T)));
但是,请注意,对于c ++对象,使用malloc被认为是非常非常过时的,像这一行更像正确 * A.valuePtr()= static_cast(new T [nnz]));
老实说,我正在努力理解你的代码应该完成什么。大多数人(包括我自己)都不会对这个“特根”课程感到满意。虽然我认为你可能会非常误解它应该如何使用。
您是否可以提供文档链接或您创建/使用此类的示例?
经过一些研究后,我遇到了This article以及This Question,您是否有可能需要使用MappedSparseMatrix
inline Scalar* valuePtr() { return &m_data.value(0); }
将返回 rvalue 指针。这不是m_data中保存的对象,也不是内部使用的指针。它是指向现有对象的指针的临时副本,试图说“将此临时副本指向其他内容”是没有意义的。
inline Scalar& value(size_t i) { return m_values[i]; }
在这种情况下,该方法返回对象的引用,引用不是指针 - (尽管&
经常会让人感到困惑)。 />
引用可以理解为原始对象,您不需要取消引用引用。请考虑以下事项。
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.
简而言之,返回的引用不是指向对象(已存在)的指针,而是是对象。这将允许您将对象设置为某个对象,或使用.
运算符调用对象上的方法,但是您无法重新分配已存在的内容,因此这是一个错误。
请考虑阅读本文关于rvale和Lvalue在C ++中的区别understanding rvalue and lvalue
答案 1 :(得分:0)
@John Bargman告诉我,我对rvalues和左值的看法是错误的,我想到了并尝试了这个:
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] = '\0';
// 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()
一样,返回一些地址类型的文字;它不会返回左值。尝试将某些东西(在这种情况下,由malloc
返回的内存块的起始地址)分配给文字(在这种情况下,某些地址如0x233ff554)是没有意义的。我想我现在明白它是如何运作的。谢谢@John Bargman!