'Can derived class member functions return different types than the base class?
I am running into a design issue with my code and I am not sure where to go. I am attempting to write a basic I/O class to write vectors of data into a text file for convenience in my research. In practice, I would like to not worry about the datatype in the array that I am writing to file and use the same interface regardless of if it is an array of ints, doubles, etc.
My basic idea was to create an AbstractColumn class, with a templated derived class to handle columns of different data. My I/O class could then contain an array of pointers to objects of this Abstract Class, and I can can add to this array as needed. See my header file below for the implementation of this.
#ifndef BASICIO_H
#define BASICIO_H
#include <vector>
#include <cstring>
#include <string>
#include <stdlib.h>
struct AbstractColumn{
virtual ~AbstractColumn() = 0;
template <class T> T* get_data(); // Issue comes in here, I think
int nrows=0;
};
template <class T>
class Column : public AbstractColumn {
public:
Column(std::vector<T>& v);
~Column();
T* get_data() {return data;}
T* data;
int nrows;
};
template <class T>
Column<T>::Column(std::vector<T>& v){
nrows = v.size();
data = static_cast<T*>(malloc(sizeof(T)*v.size())); //malloc returns void* so we need the static cast
std::memcpy(data, v.data(), v.size());
}
template <class T>
Column<T>::~Column() {}
class BasicIO {
public:
BasicIO(std::string outname) : fname(outname), ncols(0) {}
~BasicIO();
template <class T>
void attach(std::vector<T>& v, std::string name="");
void write();
inline int get_ncols() {return ncols;}
inline std::string filename() {return fname;}
private:
std::vector<AbstractColumn*> columns;
std::vector<std::string> column_names;
std::string fname;
int ncols;
};
template <class T>
void BasicIO::attach(std::vector<T>& v, std::string name){
Column<T>* col = new Column(v);
columns.push_back(col);
column_names.push_back(name);
}
#endif
My issue is coming in in trying to write the write() method that actually dumps this data to a file.
void BasicIO::write(){
// other formatting code here
for(int i = 0; i<columns.at(0)->nrows; i++){
for(int j = 0; j<ncols; j++){
outfile<<std::scientific<<std::left<<std::setw(col_width)<<(columns.at(j)->get_data())[i]<<" ";
} //^ this is causing an error
outfile<<std::endl;
}
outfile.close();
}
When I try to compile, I get the an error saying note: template argument deduction/substitution failed and couldn't deduce template parameter 'T'. Now, I think I understand what the issue is. When the compiler reaches this point, all it doesn't know what type of data is going to be returned by my get_data() function, since in the base class the return type is the template T. However, I don't see a way around this and I am very stuck. I have done a bit of reading and it seems like type erasure might be the way to go, but I also think I might be missing something simpler.
My Question All of the above context aside, my concrete question is as follows: What is the best way to have an array which holds objects (in this case columns) of generic types, specifically for the application described above? I am happy to offer any other details as needed, I just felt that my code snippets were already quite long. Thank you for reading.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
