1

Solution requirements:

  1. Pre C++11

Statements:

  1. Function someFunction exists, that accepts 2D vector as vector of string vectors: vector2d.
  2. Class someClass exists, that contains 1D vector of strings: parameters.
  3. Vector of objects of aformentioned Class is created: vectorOfClassObjects.

Problem definition:

It is possible to feed 1D vector parameter of class objects vector vectorOfClassObjects into someFunction as 2D vector? Can vector of strings, of vector of class objects be interpreted as function parameter of 2D vector of strings?

Minimum reproducible example:

#include <windows.h>
#include <iostream>
#include <cstring>
#include <vector>

class someClass{
    public:
    std::vector<std::string> parameters;
};

void someFunction(std::vector<std::vector<std::string>> vector2d){
    for(int i = 0; i < vector2d.size(); i++){
        MessageBox(NULL, vector2d[i][0].c_str(), "", MB_OK);
    }
}

int main() 
{
    // Execution #1 - expected output of Execution #2
    someFunction({{"A", "a"}, {"B", "b"}});
    
    // Execution #2
    std::vector<someClass> vectorOfClassObjects;
    
    vectorOfClassObjects.push_back(someClass());
    vectorOfClassObjects[0].parameters.push_back("C");
    vectorOfClassObjects[0].parameters.push_back("c");
    
    vectorOfClassObjects.push_back(someClass());
    vectorOfClassObjects[1].parameters.push_back("D");
    vectorOfClassObjects[1].parameters.push_back("d");  
    
    //It is possible to feed that? What syntax?
    someFunction(?vectorOfClassObjects.parameters?);
    
    return 0;
}
3
  • 2
    someFunction({{"A", "a"}, {"B", "b"}}); - this will not compile pre C++11 Commented Jul 24 at 13:57
  • what exactly to you expect to happen? The resulting 2d vector should have 1 element which equals the original 1d vector? In #1 you have a vector with 2 inner vectors each with 1 element. Thats not going to fly without creating such a vector (by copying the elements) Commented Jul 24 at 14:12
  • I have vector of class objects, and every object has vector of strings. This is kind of 2D nested vectors format. Function accepts vector of string vectors, so I wonder if it can fit as function parameter. My question comes from the fact that final item type is string so it is just about pointing to right place in memory. Surely, I can make buffer temporary vector of string vectors, copy all data in loops and then pass it to function but I wanted to avoid that. Commented Jul 24 at 15:01

2 Answers 2

1

Yes, for example creating the vector with 1 element, using pre C++11 constructor:

explicit vector( size_type count, const T& value = T(),
                 const Allocator& alloc = Allocator() );

You just need to create a vector of size 1 and copy the element that you want to use:

someFunction(std::vector<std::vector<std::string> >(1, vectorOfClassObjects[1].parameters));

Or if you are looking for the equivalent of {{"C","c"},{"D","d"}}, then you need to copy your paremeters to vector of vector of strings:

std::vector<std::vector<std::string> > arg;
arg.push_back(vectorOfClassObjects[0].parameters);
arg.push_back(vectorOfClassObjects[1].parameters);
someFunction(arg);

Either way you inevitably need to copy your vectors, I can't think of any way to e.g. reinterpret_cast your vector of classes without invoking Undefined Behavior.

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

2 Comments

1

Taking the question literally, the answer is: No.

A vector stores the elements in contiguous memory. However, the elements are not stored within the vector. Hence, if you have a 2d vector like here:

someFunction({{"A", "a"}, {"B", "b"}});

"A" is stored next to "a" in memory and "B" next to "b", but the a's are in a totally different location than the b's. Because of that, even if you have access to the vectors internal storage via its data() method, there is no way to interpret a flat vector as nested vector without creating a new vector.

I advise to generally avoid nested vectors. The big advantage of a std::vector<T> is memory locatity of the elements. As explained, a std::vector<std::vector<T>> does not have that (if you consider all Ts).


If you want to create a std::vector<std::vector<T>> from a std::vector<T> you have to create a new vector by copying (or moving) either the whole vector or its elements to the resulting vector.

2 Comments

In this case it is vector of class objects, and every object has vector of strings so it is kind of 2D nested vectors format. I thought it can somehow fit into (vector (vector string)) format. I stopped using multidimensional arrays in favor to nested vectors due to convenience of use. What else do you recommend for multidimensional data instead of nested vectors then?
@KamilK you can use a flat vector and provide 2d access via index transformations, something along the line of std::string& get(int i, int j) {return data[ i + num_rows*j ]; }. I remember a Q&A that explained it in details but I don't find it anymore

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.