I am trying to return a vector of some of the elements in a vector. I wish to modify one of the elements in this new vector and have it automatically update the value in the original vector.

I tried this:

#include <iostream>
#include <vector>

class TestClass
{
public:
  TestClass();

  void OutputData();

  //std::vector<double&> GetOddElements(); // can't do this!
  std::vector<double*> GetOddElements();
  
  double& GetElement();

private:
  std::vector<double> Data;

};

/*
// Can't do this!
std::vector<double&> TestClass::GetOddElements()
{
  std::vector<double&> oddElements;
  oddElements.push_back(this->Data[1]);
}
*/

std::vector<double*> TestClass::GetOddElements()
{
  std::vector<double*> oddElements;
  oddElements.push_back(&(this->Data[1]));
}

TestClass::TestClass()
{
  this->Data.push_back(0);
  this->Data.push_back(1);
  this->Data.push_back(2);
}

void TestClass::OutputData()
{
  for(unsigned int i = 0; i < this->Data.size(); i++)
    {
    std::cout << Data[i] << " ";
    }
}

int main(int argc, char *argv[])
{
  TestClass test;
  test.OutputData();
  std::cout << std::endl;

  std::vector<double*> oddElements = test.GetOddElements();
  std::cout << oddElements.size();
  //*(oddElements[0]) = 6;

  test.OutputData();

  return 0;
}

but it doesn't work (it outputs

0 1 2 3
3020671560 1 2 3

when I would expect/want to see:


0 1 2 3
0 6 2 3
)

And it also segfaults upon exit.

Can anyone see where I've gone wrong here?

Thanks,

David

The compiler "mike_2000_17" gives this error:
"Error at line 34: function "GetOddElements" reaches end-of-scope without returning a value"

The reason why your version that uses references is not working is because references are not copy-assignable, which is a requirement of all STL containers.

As for the bigger question. This is not a very robust way to have a sub-vector that is linked to another vector. You should look into the concept of "array views" (used in several libraries such as Boost.Graph, Boost.Multi-Array or -Index, and others too). Basically, you should wrap a reference to the vector object and define some index transformation to change the "view" that this object takes on the underlying container (this is for example a nice way to implement the transpose of a matrix without any copying).

Comments
Thanks as always Mike!

Bah, the daviddoria compiler didn't catch the missing return value and apparently I also forgot to turn on -Wall in this demo project.

The crash is gone and it works as I would expect.

I will certainly check out "array views". I need a quick solution for the time being though :)

Thanks!

Edited 5 Years Ago by daviddoria: Silly silly

This article has been dead for over six months. Start a new discussion instead.