I need to get some complex data from a library then use this data at the upper level. The data consists of 2 parts: while evaluating the data A, i get some additional data B, and the data B should be returned back in the library "as is" in order to not reevaluate it again.
So to simplify this: i get data A and data B from the library, transfer both to the upper level, use A, but then i should transfer data B back to the library.
The problem is (apart from this weird architecture) i don't want my upper level to know anything about data B, so what mechanism should i use to avoid defining library-specific data types in the upper level code? Data should be passed as a pointer.
Im thinking about void*, but C++17 allows to use std::any which i dont understand quite enough. Can i use std::unique_ptr<std::any>
? Or is it just std::any
instead?
Should it be like that?
std::any GetDataAandB()
{
std::unique_ptr ret = std::make_unique<LibraryType>(1, "");
return std::make_any<std::unique_ptr<LibraryType>>( ret);
}
How about
using LibraryData = std::pair<A, std::any>;
// Get aata of type A and B, store B in std::any -> hiding it's type
// and return both values, but with B's type hidden
LibraryData GetDataAandB()
{
A someValue;
B someValueB_HiddenType;
return LibraryData(A, std::any(B));
}
// Work with the first part of the Data
void ConsumeData(const LibraryData &data)
{
// return the data to the library
callLibrary(data);
// or do something with the individual part A
const A& dataOfTypeA = data.first;
dataOfTypeA.SomeMethod();
// Cannot really do anything with 'B', since its type is hidden
const std::any& dataOfUnknownType = data.second;
// create a new LibraryData object
LibraryData newData(dataOfTypeA, dataOfUnknownType);
callLibrary(newData);
// Or, in case we can "guess" the type:
try {
B shouldBeB=std::any_cast<B>(data.second);
// do something with B
}
catch (std::exception &e) {
// Nope, it's not of type B.
// std::any_cast will throw a bad_any_cast exception
}
}
std::any
takes care of any pointers required, so you don't have to add a unique_ptr