I'm working on a "framework" that needs to automate processing of conversion of a framework-user-defined collection of variables from/to text.
I've defined a base class for a converting text, given a variable, and templatized it. I've coded a dozen standard types (int, unsigned int, double, string, bool, time_t, etc.) and want to now support vector
of any of the types for which there's already a solution.
In short, I want to a version of this template for that works for a vector of anything, T=vector<U>
, and have it work for any element type that I've already coded, including vectors of vectors of elementary objects and so on.
Here is a base class and template in a header t.h
:
#pragma once
#include <string>
#include <vector>
using namespace std;
class BoundVarBase {
public:
BoundVarBase() {};
virtual ~BoundVarBase() {};
virtual void FromText( const char* psz ) = 0;
virtual void ToText( string* ps ) = 0;
};
template<typename T> class BoundVar: public BoundVarBase {
public:
BoundVar( T& t ) :
BoundVarBase(),
pt( &t )
{
};
virtual void FromText( const char* psz );
virtual void ToText( string* ps );
T* pt;
};
Here is t.cpp
:
#include <iostream>
#include <t.h>
template<> void BoundVar<int>::FromText( const char* psz ) {
*pt = strtol( psz, NULL, 0 );
}
template<> void BoundVar<int>::ToText( string* psOut ) {
*psOut = to_string( *pt );
}
int main( int nArg, const char* apszArg[] ) {
string s;
int i = 123;
BoundVar bi( i );
bi.ToText( &s );
cout << s << endl;
bi.FromText( "456" );
cout << i << endl;
return 0;
}
Compilation and execution look like:
> g++ --std=c++17 t.cpp -g -I. -o t
> ./t
123
456
The question is what to put that might look something like this:
template<class vector<U>> class BoundVar: public BoundVarBase {
public:
BoundVar( vector<U> U& vu ) :
BoundVarBase(),
pt( &t )
{
};
virtual void FromText( const char* psz ) {
// to be determined
};
virtual void ToText( std::string* ps ) {
string sElement;
*ps = "[ ";
for ( auto& u: pvu ) {
BoundVar bu( u );
bu.ToText( sElement );
*ps += sElement + " ";
}
*ps += " ]";
}
vector<U>* pvu;
};
that would allow this code
vector<int> ai = {1, 2, 3};
BoundVar bvi( ai );
bvi.ToText( &s );
cout << s << endl;
bvi.FromText( "[ 4 5 6 ]" );
cout << "[ " << ai[0] << " " << ai[1] << " " << ai[2] << " ]" << endl;
to output
[ 1 2 3 ]
[ 4 5 6 ]
Obviously, after getting BoundVar<int>
I could just code BoundVar<vector<int>>
. And with one type of binding that'd be easiest! But I have all the atomic C/C++ types, plus things like string, time_t and so on supported and want to have arrays of all those (and hopefully, arrays of arrays etc.) all supported with just one more template.