總之,我想知道如何將 std::tuple 型別正確存盤為 void* ,然后將其轉換回匹配的 std::tuple 型別。
問題,我的程式當前在嘗試從 void* 轉換回匹配的 std::tuple 型別時崩潰,如 B::fcn 所示。
我相信下面的代碼抓住了我想做的事情的本質。有點背景關系,我需要使用可怕的 void* 的原因是因為我有一個資料交換層,模型可以在其中將資料推送和拉取到另一個模型,因為它們具有指向目標模型的指標。資料交換層不支持 std::tuple 型別,但確實提供了通過推拉 void* 來支持任何型別的努力。如果由我決定,我會將資料交換層轉換為模板化,以便它可以直接支持任何型別的 std::tuple ,但這不是一個選項。
#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;
}
uj5u.com熱心網友回復:
fcn()正在回傳一個指向區域變數的懸空指標。void*可用于指向任何型別的物件,但它不包含它所指向的物件的記憶體。要進行型別擦除,您需要一個存盤或堆分配的記憶體來存盤物件,然后用 void* 指向它并稍后將其轉換回來以及管理它指向的記憶體。您可以查看 std::any 來管理任何型別的物件(基本上就是這樣做的)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/405191.html
標籤:
