returning vector from a class member function

Pages: 12
I have a member function of class SparceMatrixStruct which should return a vector.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
std::vector<size_t>SparceMatrixStruct::col_ind(VecVecIdx_t &refined_node_connec)
{
	for (int i = 0; i < refined_node_connec.size(); i++)
	{

		Ncol_ind_ += refined_node_connec[i].size();

	}

	std::vector<size_t>col_ind_;

	for (int i = 0; i < refined_node_connec.size(); i++) {

		for (int j = 0; j < refined_node_connec[i].size(); j++) {

			col_ind_.push_back(refined_node_connec[i][j]);
		}
	}
	
	for (int i = 0; i < Ncol_ind_; i++)
	{
		//std::cout << col_ind_[i] << "\n";
	}

	return col_ind_;
}


in the main I define,
1
2
3
VecIdx_t col_ind;
SparceMatrixStruct object;
col_ind=object.col_ind_;


and I am getting nothing. I really have problem in accessing data member. Even when I want to print the size of col_ind I get zero. but if in the class constructor I put print command everything is fine. This member function will be called in the constructor and refined_node_connec will be obtained in the constructor. any help would be appreciated.

Last edited on
Assuming VecVecIdx_t is a vector of vector of size_t, then perhaps:

1
2
3
4
5
6
7
8
9
10
auto SparceMatrixStruct::col_ind(const VecVecIdx_t& refined_node_connec)
{
	std::vector<size_t> col_ind_;

	for (const auto& vec : refined_node_connec)
		for (const auto& v : vec)
			col_ind_.emplace_back(v);

	return col_ind_;
}


I'm a bit confused. The code snippet from main() that you show doesn't call the function you are asking about.

Is there a public variable within SparceMatrixStruct named col_ind_? If so, line 10 of your function hides it.

This member function will be called in the constructor and refined_node_connec will be obtained in the constructor.


You say you call the function in your constructor. Do you assign the return value? What is in refined_node_connec? Is it empty?

There is a lot of confusion about what your code actually is.

Please post a minimally compilable version of your code. Provide the class with just the constructor and this function and any member variables that your example needs. Also provide a main() function with the lines you showed here. And include any header files you need (<vector>, etc.). If you put the whole thing inside a single code tag, we can compile it with a single mouse click.

When we see what you are really asking, we can give better answers.


Snippets. You have posted many threads and in each at most snippets of code. There seems to a lot of code, but you never show all essential parts.
Furthemore, you seem to not know basic concepts very well.


1
2
3
VecIdx_t col_ind;
SparceMatrixStruct object;
col_ind=object.col_ind_;

could be written:
1
2
SparceMatrixStruct object;
VecIdx_t col_ind = object.col_ind_ ;

However, these two statements "give" nothing -- they just create two variables.
You should print values of variables if you want to see something.
If your code does do output, why didn't you show that part too?

The col_ind_ must be a public member variable of SparceMatrixStruct.
It has the value that the default constructor of SparceMatrixStruct did set to it.
You did not show the definition of SparceMatrixStruct nor the implementation
of constructor of SparceMatrixStruct.


You asked a question about code but did not show the code. We can already tell that answer exists. Do you expect to see it?
@seeplus thanks for your answer.
@doug4 yes, there is a public variable col_ind_ in the class. Why line 10 hides the public variable col_ind_? the refined_node_connectivity is a vector of vector of size_t that is going to be obtained inside the constructor before calling the other functions. Many thanks for your answer. This is a big code. I will try to post a short version of code if it's possible.
@keskiverto it is not like I want to hide something from you. Just this is a big code and it's not possible to post all the code here.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#ifndef _SPARCEMATRIXSTRUCT_H_
#define _SPARCEMATRIXSTRUCT_H_

#include "includes.h"
#include "typedefs.h"
#include <vector>

class SparceMatrixStruct{

public:

	VecVecIdx_t Connectivities_;
	VecVecDbl_t Coordinates_;
	VecIdx_t row_ptr_;
	VecIdx_t col_ind_;

	SparceMatrixStruct() = default;
	SparceMatrixStruct(VecVecIdx_t &connect, VecVecDbl_t &coord);
	std::vector<size_t> row_ptr(VecVecIdx_t &refined_node_connec);
	std::vector<size_t> col_ind(VecVecIdx_t &refined_node_connec);

	}
};


#endif
#include "element.h"
#include "sparcematrixstruct.h"

 std::vector<size_t> SparceMatrixStruct::row_ptr(VecVecIdx_t &refined_node_connec)
{
	static std::vector<size_t>row_ptr_(refined_node_connec.size() + 1);
	for (int i = 0; i < row_ptr_.size(); i++)
	{
		if (i == 0) {
			row_ptr_[i] = 0;
		}
		else {
			row_ptr_[i] = (row_ptr_[i - 1] + refined_node_connec[i - 1].size());
		}

	}

	for (int i = 0; i < Nrow_ptr_; i++)
	{
		// std::cout << "i= " << i << " " << row_ptr_[i] << std::endl;
	}
	return row_ptr_;
}

std::vector<size_t>SparceMatrixStruct::col_ind(VecVecIdx_t &refined_node_connec)
{
	for (int i = 0; i < refined_node_connec.size(); i++)
	{

		size_t Ncol_ind_ += refined_node_connec[i].size();

	}

	std::vector<size_t>col_ind_;

	for (int i = 0; i < refined_node_connec.size(); i++) {

		for (int j = 0; j < refined_node_connec[i].size(); j++) {

			col_ind_.push_back(refined_node_connec[i][j]);
		}
	}
	
	for (int i = 0; i < Ncol_ind_; i++)
	{
		//std::cout << col_ind_[i] << "\n";
	}

	return col_ind_;
}

Now in the main I will try this
1
2
		SparceMatrixStruct object1(Connectivity, Coordinate);
		size_t Nrow_ptr=object1.Nrow_ptr_;

this works
but
VecIdx_t row_ptr = object1.row_ptr_;
doesn't work.

I know about this basic :)
1
2
3
VecIdx_t col_ind;
SparceMatrixStruct object;
col_ind=object.col_ind_;

should be written as
1
2
SparceMatrixStruct object;
VecIdx_t col_ind = object.col_ind_ ;


but this is not final version of code, sometimes you change a lot of things in code and something like this remains there
Last edited on
With:
1
2
3
4
5
class SparceMatrixStruct {
public:
	VecIdx_t col_ind_;
	SparceMatrixStruct() = default;
};

We can explain the:
1
2
SparceMatrixStruct object;
VecIdx_t col_ind = object.col_ind_ ;

It is like you had:
1
2
VecIdx_t object_col_ind_ ;
VecIdx_t col_ind = object_col_ind_ ;

That is what your default constructor SparceMatrixStruct() does.
If VecIdx_t object_col_ind_ ; creates "nothing", then nothing you get.


In the other case, (which was not mentioned in OP):
1
2
3
SparceMatrixStruct object1(Connectivity, Coordinate);
size_t Nrow_ptr = object1.Nrow_ptr_;
VecIdx_t row_ptr = object1.row_ptr_;

you call the other constructor.

Q: Where in it do you set the Nrow_ptr_ and row_ptr_?
A: Nowhere, directly.

However, the constructor calls another member function:
1
2
3
4
5
6
SparceMatrixStruct::SparceMatrixStruct(VecVecIdx_t &connect, VecVecDbl_t &coord)
{
  // code
  row_ptr( refined_node_connec );
  // code
}


Q: Does that set the member variables?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
std::vector<size_t> SparceMatrixStruct::row_ptr(VecVecIdx_t &refined_node_connec)
{
	Nrow_ptr_ = refined_node_connec.size() + 1; // <-- HERE, Yes!
	static std::vector<size_t> snafu( refined_node_connec.size() + 1 );
	for (int i = 0; i < Nrow_ptr_; i++)
	{
		if (i == 0) {
			snafu[i] = 0;
		}
		else {
			snafu[i] = (snafu[i - 1] + refined_node_connec[i - 1].size());
		}
	}

	for (int i = 0; i < Nrow_ptr_; i++)
	{
		// std::cout << "i= " << i << " " << snafu[i] << std::endl;
	}
	return snafu;
}

A: The value of Nrow_ptr_ is set.
The value of row_ptr_ is not set.


Was your intention to store the value returned by that function in row_ptr_?

Then do so:
1
2
3
4
5
6
SparceMatrixStruct::SparceMatrixStruct(VecVecIdx_t &connect, VecVecDbl_t &coord)
{
  // code
  row_ptr_ = row_ptr( refined_node_connec );
  // code
}
Thank you so much for your time and your comprehensive explanation. why you used static here
static std::vector<size_t> snafu( refined_node_connec.size() + 1 );
Last edited on
I didn't. You did.
I was trying to use pointer to member function and I used static, I thought I removed this part before posting the question and I thought you had a reason for that.sorry, it was my bad. These row_ptr and col_ind functions have returning type. how could I access the row_ptr_ and col_ind_ if they were in a void function?I'm thinking about having the desired output with refrence in the void function. Is that a good idea?
Last edited on
You do modify member variable Nrow_ptr_ in member function row_ptr().
If you can modify one member, then why don't you modify the other?


The member row_ptr_ is a vector? Why do you have member Nrow_ptr_ at all?
Vector knows its size. Having the size info in two places is redundant and can lead to errors.
1
2
3
4
5
6
7
8
9
10
void
SparceMatrixStruct::row_ptr( VecVecIdx_t &refined_node_connec )
{
  row_ptr_.resize( refined_node_connec.size() + 1 );
  row_ptr_[0] = 0;
  for ( int i = 1; i < row_ptr_.size(); i++ )
  {
    row_ptr_[i] = row_ptr_[i - 1] + refined_node_connec[i - 1].size();
  }
}
Last edited on
Yes, you are right, I'll modify it. As you know we don't have any returning value by void function. Imagine I have a class member function which is a void function and calculate one of my class variable which is a vector of vector. and this void will be called inside the class constructor. Now I need that class variable. Is there any way to access this class variable. I don't want to use defining global variable.


Last edited on
Is there any way to access this class variable.

It seems that we don't communicate.

What do you do here?
1
2
3
std::vector<size_t> SparceMatrixStruct::row_ptr(VecVecIdx_t &refined_node_connec)
{
	Nrow_ptr_ = refined_node_connec.size() + 1;
sorry for my late reply. I modified it in the above code.
That is not a reply to question.

What did the Nrow_ptr_ = refined_node_connec.size() + 1; do?
Just this is a big code and it's not possible to post all the code here.


I would suggest that this is the problem.

Instead of writing 1000s of lines of code and then asking us why it doesn't work, write just a small portion. Get that to work. If the small portion doesn't work, it's a lot easier to post your code on the forum.

When you get the small portion to work add a little bit to it. If that doesn't work, the problem is usually (but not always) in the portion you added. That will help you track things down more easily.

Small steps. Compile and test often. Don't move on until it works.
@keskiverto
Nrow_ptr_ = refined_node_connec.size() + 1; do?
this is the number of row_ptr in strong a matrix in csr format. In this format, one vector stores the number of non_zero element, one vector contains the row extents(row_ptr) and the other one has the number of column of non_zero element.
Bests,
Yes, but what did the statement do?

Lets make an another example for this question:
1
2
3
4
5
6
7
8
9
class Example {
  int answer;
public:
  void memfun();
};

void Example::memfun() {
  answer = 42;
};

What does the bold statement do? (This case is analogous to what you had.)
Why don't you upload the whole project - maybe to github or dropbox or ...
I am sure some more advanced user can spot the problem when seeing and running the whole project.
Is it maybe a commercial project ?
Pages: 12