Akshay
Akshay

Reputation: 2763

Adding a map of string vector and different datatype vector

As suggested in https://stackoverflow.com/a/44884240/3782963. I created a method of return type std::map<std::string, Spikes::data> get_data1(). I create a struct called data:

struct data {

            std::vector<Eigen::MatrixXd> samples;
            std::vector<std::string> sample_names;
            int index = -1;
        };

and placed it in my namespace and out of the class FileReader.

My method looks like:

std::map<std::string, Spikes::data> FileReader::get_data1() {
    std::map<std::string, Spikes::data> content;

    std::vector<Eigen::MatrixXd> samples;
    std::vector<std::string> sample_names;

    for (auto i : list_dir()) {
        if (contains_number(i)) {
            samples.push_back(load_csv(location + "/" + i));
            sample_names.push_back(i);
        }
    }

    content.emplace(std::make_pair("samples", Spikes::data{samples,0}));
    content.emplace(std::make_pair("sample_names", Spikes::data{sample_names,1}));

    return content;

And in my main.cpp I am calling this method as:

for (auto i:a.get_data1()["samples"].samples){
        std::cout<<i;
    }

But I get the following errors:

/cygdrive/c/Users/aksha/Box Sync/MyDrive/Projects/Akshay-GitHub/libSpikes/libSpikes/src/Core/FileReader.cpp: In member function 'std::map<std::basic_string<char>, Spikes::data> Spikes::FileReader::get_data1()':
/cygdrive/c/Users/aksha/Box Sync/MyDrive/Projects/Akshay-GitHub/libSpikes/libSpikes/src/Core/FileReader.cpp:154:69: error: no matching function for call to 'Spikes::data::data(<brace-enclosed initializer list>)'
     content.emplace(std::make_pair("samples", Spikes::data{samples,0}));
                                                                     ^
In file included from /cygdrive/c/Users/aksha/Box Sync/MyDrive/Projects/Akshay-GitHub/libSpikes/libSpikes/src/Core/FileReader.cpp:3:0:
/cygdrive/c/Users/aksha/Box Sync/MyDrive/Projects/Akshay-GitHub/libSpikes/libSpikes/src/Core/FileReader.h:13:12: note: candidate: Spikes::data::data()
     struct data {
            ^
/cygdrive/c/Users/aksha/Box Sync/MyDrive/Projects/Akshay-GitHub/libSpikes/libSpikes/src/Core/FileReader.h:13:12: note:   candidate expects 0 arguments, 2 provided
/cygdrive/c/Users/aksha/Box Sync/MyDrive/Projects/Akshay-GitHub/libSpikes/libSpikes/src/Core/FileReader.h:13:12: note: candidate: Spikes::data::data(const Spikes::data&)
/cygdrive/c/Users/aksha/Box Sync/MyDrive/Projects/Akshay-GitHub/libSpikes/libSpikes/src/Core/FileReader.h:13:12: note:   candidate expects 1 argument, 2 provided
/cygdrive/c/Users/aksha/Box Sync/MyDrive/Projects/Akshay-GitHub/libSpikes/libSpikes/src/Core/FileReader.h:13:12: note: candidate: Spikes::data::data(Spikes::data&&)
/cygdrive/c/Users/aksha/Box Sync/MyDrive/Projects/Akshay-GitHub/libSpikes/libSpikes/src/Core/FileReader.h:13:12: note:   candidate expects 1 argument, 2 provided
/cygdrive/c/Users/aksha/Box Sync/MyDrive/Projects/Akshay-GitHub/libSpikes/libSpikes/src/Core/FileReader.cpp:155:79: error: no matching function for call to 'Spikes::data::data(<brace-enclosed initializer list>)'
     content.emplace(std::make_pair("sample_names", Spikes::data{sample_names,1}));
                                                                               ^
In file included from /cygdrive/c/Users/aksha/Box Sync/MyDrive/Projects/Akshay-GitHub/libSpikes/libSpikes/src/Core/FileReader.cpp:3:0:
/cygdrive/c/Users/aksha/Box Sync/MyDrive/Projects/Akshay-GitHub/libSpikes/libSpikes/src/Core/FileReader.h:13:12: note: candidate: Spikes::data::data()
     struct data {
            ^
/cygdrive/c/Users/aksha/Box Sync/MyDrive/Projects/Akshay-GitHub/libSpikes/libSpikes/src/Core/FileReader.h:13:12: note:   candidate expects 0 arguments, 2 provided
/cygdrive/c/Users/aksha/Box Sync/MyDrive/Projects/Akshay-GitHub/libSpikes/libSpikes/src/Core/FileReader.h:13:12: note: candidate: Spikes::data::data(const Spikes::data&)
/cygdrive/c/Users/aksha/Box Sync/MyDrive/Projects/Akshay-GitHub/libSpikes/libSpikes/src/Core/FileReader.h:13:12: note:   candidate expects 1 argument, 2 provided
/cygdrive/c/Users/aksha/Box Sync/MyDrive/Projects/Akshay-GitHub/libSpikes/libSpikes/src/Core/FileReader.h:13:12: note: candidate: Spikes::data::data(Spikes::data&&)
/cygdrive/c/Users/aksha/Box Sync/MyDrive/Projects/Akshay-GitHub/libSpikes/libSpikes/src/Core/FileReader.h:13:12: note:   candidate expects 1 argument, 2 provided

I have no clue as to what is going on.

I have even tried doing:

content["samples"] = Spikes::data{samples,0};
content["sample_names"] = Spikes::data{sample_names,1};

I still get the same error. Any help would be highly appreciated.

Upvotes: 0

Views: 63

Answers (2)

Dean Seo
Dean Seo

Reputation: 5683

As suggested in https://stackoverflow.com/a/44884240/3782963. I created a method of return type std::map get_data1().

The suggested answer clearly states that you need to implement constructors for data:

struct data 
{
    // constructors... <- here

    std::vector<Eigen::MatrixXd> samples;
    std::vector<std::string> names;
    int index = -1;
};

@SamVarshavchik described the reason well.

I assume your intention would be having constructors as follows:

// Constructors
data(std::vector<Eigen::MatrixXd> && rhs, int idx) 
{
    samples = std::move(rhs);
    index = idx;
}

data(std::vector<std::string> && rhs, int idx) 
{
    samples = std::move(rhs);
    index = idx;
}

content.emplace(std::make_pair("samples", Spikes::data{ std::move(samples), 0}));
content.emplace(std::make_pair("sample_names", Spikes::data{ std::move(sample_names), 1}));

Upvotes: 1

Sam Varshavchik
Sam Varshavchik

Reputation: 118340

When you use value initialization for a simple structure/aggregate/etc...:

Spikes::data{samples,0}

You must initialize every member of this structure.

Your data class contains three members, the first two of them are vectors, and the third class member an int. Obviously initializing a std::vector of std::strings using a plain integer 0 is not going to go anywhere. This 0 will be interpreted as a value to initialize the second member of your struct, since it's the second value in the initialization list. The second member of your struct is a std::vector of std::strings, and the compiler will, essentially, attempt to initialize the second member accordingly, something like this:

std::vector<std::string> sample_names{0};

This is what your attempt at initialization boils down to, and this is not going to go very far...

You cannot arbitrarily skip class members, when using value initialization. You must initialize every class member, in order. In this case, your likely intent is probably something along these lines:

Spikes::data{samples,{},0}

Thusly initializing the second vector with an empty sub-initialization list. Similarly, your second attempt at initialization:

Spikes::data{sample_names,1}

It suffers from the same problem. Your likely intentions here are probably:

Spikes::data{{}, sample_names,1}}

i.e. initializing the first std::vector member with an empty initialization list, and then initializing the second std::vector accordingly.

Upvotes: 1

Related Questions