0

I am trying to build an unordered_map to vector variables which are members of my class. I can do this using standard pointers * but this requires the use of (*x) to access the vector. I wondered if std::reference_wrapper would be cleaner, but can't get it to work.

#include <unordered_map>
#include <iostream>
#include <vector>
#include <functional>

class model_class {

private:

  static constexpr auto MaxHerds = 1 ;
  static constexpr int MaxInitValues = 5 ;
  static constexpr int MaxAnimals = 2 ;

  std::vector< double > MamCellsF ;
  std::vector< std::vector< double > > InitCond ;

public:

  std::unordered_map< std::string , std::reference_wrapper< std::vector< double > > > vector;
  std::unordered_map< std::string , std::vector< std::vector< double > >* > array;

  model_class ( ) :
    // initialise vectors
    MamCellsF( MaxHerds , 0.07 ) ,
    InitCond( MaxAnimals , std::vector< double > ( MaxInitValues , 0.7 ) )
  {
     // point to variables from model
     vector.insert({"MamCellsF", std::ref(MamCellsF)});
     array["InitCond"] = &InitCond;

     // assign to vectors
     MamCellsF = { 0.001 , 0.002 }  ; // warning: automatic resizing
     InitCond = { { 1.0 , 550 , 3.5 , 1 , 4 } ,
     { 2.0 , 625 , 3.5 , 5 , 4 } } ;
  }

  void print_values(){

    // access the vectors
    double a = vector["MamCellsF"].get()[1]; // error: "no matching function call to `std::reference_wrapper<std::vector<double>>::reference_wrapper()"
    double b = (*array["InitCond"])[0][1];
    std::cout << a << std::endl;
    std::cout << b << std::endl;

  }

};

void test()
{

  model_class model;
  model.print_values();

}

1 Answer 1

2

vector["MamCellsF"] returns a reference to the value in the map. So if there isn't one it must be constructed first. That uses default constructor but std::reference_wrapper is not default constructible hence the error.

I think that STL containers are safe with T that are not default constructible but their operations might be limited. So I don't recommend that.

Sign up to request clarification or add additional context in comments.

4 Comments

I thought I have already inserted the reference into the map.
@SimonWoodward That doesn't matter. This is compile error, because in that operator is code that does the adding and the default construction and it cannot be compiled.
Are you saying that std::reference_wrapper is not the right tool for what I am trying to do? Is it ok to use standard pointers then?
@SimonWoodward It has the sematics that you want, but the cost to it is that it's not default-constructible and STL containers don't work nicely with that. So I would stick to pointers probably.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.