In summary, I would like to know how to properly store a std::tuple type as void* and later convert it back into the matching std::tuple type.
Problem, my program is currently crashing on the attempted cast from void* back to the matching std::tuple type as shown in B::fcn.
I believe the code below captures the essence of what I would like to be able to do. A bit of context, the reason I need to use the dreaded void* is because I have a data exchange layer where models can push and pull data to another model given they have the pointer to the target model. The data exchange layer does not support std::tuple type but does provide a ditch effort to support any type through pushing and pulling void*. If it were up to me I would convert the data exchange layer to be templated so that it could directly support std::tuple of any type but this is not an option.
#include <iostream>
#include <string>
#include <vector>
#include <tuple>
/* Variadic method for streaming std::vector type to cout */
template<typename T>
std::ostream& operator<<(std::ostream& stream, std::vector<T> r)
{
//Save repetitive calls to check .size()
int container_size = r.size();
//Pre-allocate loop iterator
int indx = 0;
//Check if the input vector is empty
if( container_size > 0 )
{
//Stream character for the start of a container
stream << "{ ";
//For each element of the input container, could be a value or nested container
for(indx; indx < container_size; indx++)
{
//Execute based on iterator position within container
if( indx < ( container_size - 1 ) )
{
//Print value, or recurse nested container to << template
stream << r[ indx ] << ", ";
}
else
{
//Stream last value and terminate with character
stream << r[ indx ] << " }";
}
}
}
//Default & final execution
return stream;
};
/* Start: Recursive variadic methods for streaming std::tuple type to cout */
template <size_t n, typename... T>
typename std::enable_if<(n >= sizeof...(T))>::type
print_tuple(std::ostream&, const std::tuple<T...>&)
{}
template <size_t n, typename... T>
typename std::enable_if<(n < sizeof...(T))>::type
print_tuple(std::ostream& os, const std::tuple<T...>& tup)
{
if (n != 0)
os << ", ";
os << std::get<n>(tup);
print_tuple<n+1>(os, tup);
}
template <typename... T>
std::ostream& operator<<(std::ostream& os, const std::tuple<T...>& tup)
{
os << "[";
print_tuple<0>(os, tup);
return os << "]";
}
/* End: Recursive variadic methods for streaming std::tuple type to cout */
/* An tuple alias for brevity */
using MyType = std::tuple< int, std::vector<std::string> >;
/* Dummy class for making an std::tuple and returning it as a void* */
class A
{
public:
void* fcn()
{
void *val;
int p1 = 123;
std::vector<std::string> p2 = { "Hello", "World" };
MyType p3 = std::make_tuple( p1, p2 );
val = &p3;
return val;
}
};
/* Dummy class for: receiving a void* and converting it to the expected type aliased as MyType; streaming private data member to cout */
class B
{
public:
void fcn(void *x)
{
p1 = *static_cast< MyType* >(x);
}
void print()
{
std::cout<<"\nP1 = "<<p1<<"\n";
}
private:
MyType p1;
};
/* Main program */
int main()
{
//Make instance of class A
A a;
//Make instance of class B
B b;
//Test: std::tuple -> void* -> std::tuple
b.fcn( a.fcn() );
//Test: print private data member of B
b.print();
//Exit main program
return 0;
}
Aucun commentaire:
Enregistrer un commentaire