Reputation: 127
I am trying to do a C++ exercise, which consists of a test code (main.cpp) and a header file (vcvec.h). The test code supposed to remain untouched, whereas the included header file should satisfy the test code (this is what I have to write from scratch).
In this exercide I have to write an extension to the std::vector by inheritance. I managed to solve most parts of this exercise, now, I will attach below only the relevant part of the code.
main.cpp (test code)
#include <string>
#include "vcvec.h"
int main()
{
version_controlled_vector<unsigned int> v;
version_controlled_vector<std::string> a;
v.push_back( 1 );
a.push_back("C++");
std::vector<std::vector<std::string> > hista = a;
std::vector<std::vector<int> > histv = v;
}
vcvec.h
#ifndef VCVEC_H
#define VCVEC_H
#include <vector>
template<class T>
class version_controlled_vector : public std::vector<T>
{
private:
std::vector<std::vector<T>> history;
};
#endif // VCVEC_H
This code generates the following compile errors:
main.cpp: In function ‘int main()’:
main.cpp:12:52: error: conversion from ‘version_controlled_vector<std::basic_string<char> >’ to non-scalar type ‘std::vector<std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > >, std::allocator<std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > > > >’ requested
std::vector<std::vector<std::string> > hista = a;
^
main.cpp:13:44: error: conversion from ‘version_controlled_vector<unsigned int>’ to non-scalar type ‘std::vector<std::vector<int> >’ requested
std::vector<std::vector<int> > histv = v;
^
How can I assign an instance of version_controlled_vector to an std::vector type? The only solution I can think of, is an appropriate copy-constructor, but it should take place in the std::vector class, so it is not an option.
Upvotes: 1
Views: 206
Reputation: 206607
These are the options I can think of:
Provide a function that returns a reference to the private data.
template<class T>
class version_controlled_vector : public std::vector<T>
{
std::vector<std::vector<T>> const& getHistory() {return history;} const
private:
std::vector<std::vector<T>> history;
};
Then, in the client code, use:
std::vector<std::vector<std::string> > hista = a.getHistory();
Provide an auto cast operator function
template<class T>
class version_controlled_vector : public std::vector<T>
{
public:
operator std::vector<std::vector<T>> const& () {return history;} const
private:
std::vector<std::vector<T>> history;
};
Then, in the client code, use:
std::vector<std::vector<std::string> > hista = a;
Make the data public
so others can use directly (Not recommended)
std::vector<std::vector<std::string> > hista = a.history;
Update, in response to comment by OP
I am not sure how your files look like, but the following code, when put in one .cc file, compiles and builds for me.
#include <vector>
template<class T>
class version_controlled_vector : public std::vector<T>
{
public:
operator std::vector<std::vector<T> > const& () {return history;}
private:
std::vector<std::vector<T> > history;
};
#include <string>
int main()
{
version_controlled_vector<unsigned int> v;
version_controlled_vector<std::string> a;
v.push_back( 1 );
a.push_back("C++");
std::vector<std::vector<std::string> > hista = a;
std::vector<std::vector<unsigned int> > histv = v;
}
Upvotes: 3