我只会粘贴相关代码
模板类:
template<class TMsgType, class TKeyType>
struct mapped_subscription_handler
{
protected:
typedef std::function<void(TKeyType const &, TMsgType*)> handler_t;
typedef std::unordered_multimap<TKeyType, subscr_obj<handler_t>> map_t;
public:
void call(TKeyType const & key, TMsgType* msg)
{
//blah
}
public:
handler_id_t register_handler(TKeyType const & key, handler_t handler)
{
//blah
}
void unregister_handler(TKeyType key, handler_id_t id)
{
//blah
}
private:
map_t _map;
};
实施班:
typedef clients::mapped_subscription_handler<NS_Snap::NS_MD::DepSnapshot, clients::header_info<NS_Snap::NS_DEF::Header>::mdid_t> depth_handler_t;
typedef clients::mapped_subscription_handler<NS_Snap::NS_MD::TrdSnapshot, clients::header_info<NS_Snap::NS_DEF::Header>::mdid_t> trd_handler_t;
class data_client
:public depth_handler_t,
public trd_handler_t
{
public:
data_client(const std::string & host, int port);
virtual ~data_client();
clients::handler_id_t register_on_connect(std::function<void()> connect_handler);
using depth_handler_t::register_handler;
using trd_handler_t::register_handler;
using depth_handler_t::unregister_handler;
using trd_handler_t::unregister_handler;
};
用法:
class time_comparer
{
internal_clients::data_client *_int_client;
void whenever()
{
//Compiler complains about ambiguous call here.
_int_client->register_handler(rep->GetId(), boost::bind(&time_comparer::on_internal_depth, this, _1, _2));
}
void on_internal_depth(uint64_t const & key, NS_Snap::NS_MD::DepSnapshot* depth)
{
//blah
}
};
当我调用register_handler
时,编译器会抱怨含糊不清的引用。我不能识别我正在呼叫的register_handler
(基于boost::bind
类型)吗?否则,我必须使用丑陋的类名限定调用。
编辑:
基于Sebastian Redl
这个更简单的例子遇到了同样的问题
#include <iostream>
#include <functional>
template<class T>
struct test_template
{
template<class TArg>
void do_(T t, TArg arg)
{
t(arg);
}
};
class test_class :
public test_template<std::function<void(char*)>>,
public test_template<std::function<void(int)>>
{
public:
using test_template<std::function<void(char*)>>::do_;
using test_template<std::function<void(int)>>::do_;
};
int main()
{
test_class tc;
tc.do_([](int x){std::cout << x << std::endl; }, 10);
tc.do_([](char* x) {std::cout << x << std::endl; }, "what");
return 0;
}
有没有办法在没有明确指定调用时的重载?即
tc.test_template<std::function<void(int)>>::do_([](int x){std::cout << x << std::endl; }, 10);
答案 0 :(得分:2)
在简化示例中,您可以使用SFINAE来删除主要基于非函数参数的模板。
template<class T>
struct test_template
{
template<class TArg>
auto do_(T t, TArg arg)
-> decltype(t(arg), void())
{
t(arg);
}
};
答案 1 :(得分:0)
std::function
对它的转换非常宽松,特别是如果传递的函数对象不兼容,标准不要求转换为SFINAEd。因此,两种函数类型似乎都可以从绑定中构造出来,这就是为什么会出现歧义。