C++中回调矩阵实现的数据结构
我正在寻找一种数据结构,它将有助于实现一个决策矩阵,一方面是非POD类型的参数,另一方面是回调函数 我特别想在参数集/元组和回调函数之间使用某种一对一的对应关系。在这种情况下,存在一组特定的参数值将导致回调的明确定义,类似于:C++中回调矩阵实现的数据结构,c++,data-structures,callback,C++,Data Structures,Callback,我正在寻找一种数据结构,它将有助于实现一个决策矩阵,一方面是非POD类型的参数,另一方面是回调函数 我特别想在参数集/元组和回调函数之间使用某种一对一的对应关系。在这种情况下,存在一组特定的参数值将导致回调的明确定义,类似于: template<typename t1, typename t2, ...> (t1 arg1 == _1_1, t2 arg2 == _2_1, t3 arg3 == _3_1) -> void callback_func_1() (t1 arg
template<typename t1, typename t2, ...>
(t1 arg1 == _1_1, t2 arg2 == _2_1, t3 arg3 == _3_1) -> void callback_func_1()
(t1 arg1 == _1_2, t2 arg2 == _2_2, t3 arg3 == _3_2) -> void callback_func_2()
(t1 arg1 == _1_3, t2 arg2 == _2_3, t3 arg3 == _3_3) -> void callback_func_3()
...
(t1 arg1 == _1_n, t2 arg2 == _2_n, t3 arg3 == _3_n) -> void callback_func_n^3()
应该有一个搜索方法来选择与参数集对应的回调函数,这些参数的值等于C++类伪代码中的给定值:
template<typename t1, typename t2, ...>
void CallbackMatrix::SelectCallback(t1& arg1, t2& arg2, t3& arg3, ...)
{
BOOST_FOREACH(const auto& item, Matrix)
{
if( arg1 == item.arg1 && arg2 == item.arg2 && ... )
{
item.function();
break;
}
}
}
从我的观点来看,这种数据结构可能对许多开发人员有用,所以我正在寻找Boost?中某个地方的库实现?。不过如果有人提供他自己版本的数据结构,我会非常感激
谢谢。我觉得你要找的东西很复杂。您确定无法重新设计程序来避免此问题吗
无论如何,让我们把你的非POD类型看作类MyType
最后,使用一个映射,其中键是MyType,这就是为什么我们需要在MyType中重载运算符<,而值是指向MyFunc派生对象的指针std::map<MyType, MyFunc*> Matrix;
//feed you map
MyType t1( 42, 0., "hey" );
MyType t2( 7, 12.34, "cool" );
MyFunc *f1 = new FirstImpl;
MyFunc *f2 = new SecondImpl;
Matrix.insert( std::make_pair<MyType, MyFunc*>( t1, f1 ) ); // can also use the C++11 map::emplace
Matrix.insert( std::make_pair<MyType, MyFunc*>( t2, f2 ) );
然后,SelectCallback变为
void CallbackMatrix::SelectCallback( std::vector< boost::any > args )
{
for_each(const auto& item : Matrix)
if( args.size() == item.first.myVec.size() )
{
auto mismatch_pairs = std::mismatch( args.begin(),
args.end(),
item.first.myVec.begin() );
if( mismatch_pairs.empty() ) // if no mismatch
{
item.second->function( item.first );
break;
}
}
}
当然,用数据填充MyType对象会略有不同,如
MyType t1;
t1.myVec.push_back( 42 );
t1.myVec.push_back( 0. );
t1.myVec.push_back( static_cast<char const *>("hey") );
谢谢你的回复,我从他们身上学到了很多,尤其是战略模式。但老实说,我需要一个更抽象的解决方案,可能是基于可变模板?这将提供一个机会来构建和操作您的答案中提到的std::map,它的MyType复杂度=任意维数。@Vitalyisev好的,我提出第二个解决方案。你们觉得怎么样?谢谢你们,你们的第二个解决方案对我来说很清楚,所以我会在网站允许我这么做的时候尽快奖励赏金。我唯一不明白的是,为什么要将回调打包到类中,我们从中获得了什么?@VitalyIsaev嗯,我想这是风格的问题。如果我要解决你的问题,我会这样做。但您确实可以使用C++11 std::function+std::bind或boost::function+boost::bind将通用回调用作映射值。
template<typename t1, typename t2, ...>
void CallbackMatrix::SelectCallback(t1& i, t2& d, t3& s, ...)
{
for_each(const auto& item : Matrix)
{
if( i == item.first.i && d == item.first.d && ... )
{
item.second->function( item.first );
break;
}
}
}
struct MyType
{
std::vector< boost::any > myVec;
bool operator<( const MyType& other)
{
if( myVec.size() != other.myVec.size() )
return false;
else
{
for( int i = 0; i < myVec.size(); ++i )
{
if( myVec[i] < other.myVec[i] ) // so types must be comparable
return true;
else if( myVec[i] > other.myVec[i] )
return false;
}
return false; // meaning myVec and other.myVec are identical
}
}
};
void CallbackMatrix::SelectCallback( std::vector< boost::any > args )
{
for_each(const auto& item : Matrix)
if( args.size() == item.first.myVec.size() )
{
auto mismatch_pairs = std::mismatch( args.begin(),
args.end(),
item.first.myVec.begin() );
if( mismatch_pairs.empty() ) // if no mismatch
{
item.second->function( item.first );
break;
}
}
}
MyType t1;
t1.myVec.push_back( 42 );
t1.myVec.push_back( 0. );
t1.myVec.push_back( static_cast<char const *>("hey") );