c++中实现回调矩阵的数据结构
Data structure for callback matrix implementation in C++
我正在寻找数据结构,这将有利于决策矩阵的实现,一方面是非pod类型的参数,另一方面是回调函数。
我特别想在集合/元组参数和回调函数之间使用某种一对一的对应关系。在这种情况下,存在一组特定的参数值将导致回调的明确定义,类似于:
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
struct MyType
{
int i;
double d;
std::string s;
MyType(...) {...} //ctor
bool operator<( const MyType& other) //define a 'lexicographical' order
{
if( i < other.i
|| ( i == other.i && d < other.d )
|| ( i == other.i && d == other.d && s.compare( other.s ) < 0 ) )
{
return true;
}
else
return false;
}
};
那么,让我们使用策略模式来代替回调。
class MyFunc
{
public:
virtual void function( MyType& ) = 0;
virtual ~MyFunc() = default;
};
class FirstImpl : public MyFunc
{
public:
void function( MyType& t ) {...} // do something
};
class SecondImpl : public MyFunc
{
public:
void function( MyType& t ) {...} // do something else
};
最后,使用键为MyType的map(这就是为什么我们需要重载操作符<(在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 ) );
然后,你可以调用select函数
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;
}
}
}
这个解决方案适合你吗?
编辑-第二个解决方案
注意:下面是伪代码;我没有尝试编译它!但是思想在这里。
我们仍然需要一个MyType
类来重载操作符<注意,MyType
变成了POD。这是个问题吗?>
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
}
}
};
然后,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") );
相关文章:
- pcap_handler回调仅在使用 NPCAP v0.9991 时包含空数据包
- CURLOPT_INTERLEAVEFUNCTION回调函数始终接收 nullptr 作为用户数据指针
- 如何使用软化工具包从 OPC UA 服务器异步读取操作回调中的数据值响应中获取 NodeId 详细信息
- 将任意数据传递给不接受"void* userarg"的C++回调
- 在通过 P/Invoke 获取的 C++ 结构上设置 C# 回调
- 是否可以检查存储在堆栈上的单词是否是回文,而C++中没有任何附加数据结构
- 通过回调提供数据服务
- 共享指针和回调注册的结构.由于我之外的原因调用回调时,原始指针值发生了变化
- 如何使用传递给 C# 代码回调的 C/C++本机结构
- 如何在 c++ 结构中的 void* 变量中调用存储函数(回调)
- 如何使用GLUT的回调操作数据
- 由值传递的结构,在 C -> C++ 回调函数期间损坏 (gcc 4.1)
- 我可以在SERVICE_TABLE_ENTRYA结构中使用成员函数作为回调吗
- 如何在C++中向epoll_event结构传递回调函数指针
- 带有字符串抛出bad_alloc用户数据的 curl 写入回调
- 对用户数据进行严格的别名和回调
- 托管函数在非托管结构(C++、C#)中作为回调函数传递的问题
- 如何使用 boost::bind 将类/结构实例作为参数传递给回调
- 使用重叠结构进行回调
- c++中实现回调矩阵的数据结构