简体   繁体   English

c++ 模板参数编译器无法推断

[英]c++ template parameter compiler can not deduce

here is function to register.这里是 function 注册。

template <typename ReqT, typename RespT>
bool RegisterCmdHandler(int cmd_id, std::function<int(int, const ReqT&, RespT&)> sync_handler) {
    // ... do something with sync_handler and register it for later callback
    return true;
}

and a specific handler to register:以及要注册的特定处理程序:

int SomeHandler(int id, const Foo& req, Bar& resp) {
    // ... specific logic
}

now I want to apply the Handler to Register Function, compiler complains现在我想将处理程序应用于注册 Function,编译器抱怨

RegisterCmdHandler(1, SomeHandler); // ERROR, compiler can not deduce

while specificly write out the type is OK:而具体写出类型是可以的:

RegisterCmdHandler<Foo, Bar>(1, SomeHandler); // OK, compiler can deduce

but the latter has ugly API.但后者有丑陋的API。 How can I get the first on work?我怎样才能在工作中获得第一名?

How can I get the first on work?我怎样才能在工作中获得第一名?

Add an overload for plain function pointers:为普通的 function 指针添加重载:

template <typename ReqT, typename RespT>
bool RegisterCmdHandler(int cmd_id, int(*sync_handler)(int, const ReqT&, RespT&)) {
    std::function<int(int, const ReqT&, RespT&)> sync_handler2(sync_handler);
    return RegisterCmdHandler(cmd_id, sync_handler2);
}

How can I get the first on work?我怎样才能在工作中获得第一名?

I see some ways.我看到了一些方法。

(1) If you can modify the RegisterCmdHandler() function and you don't need to know, inside it, what types ReqT and RestT are, I suggest you to avoid at all std::function and accept sync_handler as a simple template type. (1) 如果您可以修改RegisterCmdHandler() function并且您不需要知道其中ReqTRestT是什么类型,我建议您完全避免std::function并接受sync_handler作为简单的模板类型.

I mean我是说

template <typename F>
bool RegisterCmdHandler (int cmd_id, F sync_handler) {
// ... do something with sync_handler
return true;
}

This is a very flexible solution because F can be a function, a function pointer, a std::function , a lambda (also a generic lambda, so this solution is more flexible than using std::function ), another type of class/struct with an operator() , a value returned from a std::bind . This is a very flexible solution because F can be a function, a function pointer, a std::function , a lambda (also a generic lambda, so this solution is more flexible than using std::function ), another type of class/带有operator()的结构,从std::bind返回的值。 In short: a generic callable.简而言之:一个通用的可调用对象。

(2) If you can modify the RegisterCmdHandler() function but you need to know (and use) the ReqT and RestT , you can follows the plain function pointer way (see Maxim Egorushkin's answer for the syntax). (2) 如果您可以修改RegisterCmdHandler() function您需要了解(并使用) ReqTRestT ,则可以遵循普通的 function 指针方式(有关语法,请参见 Maxim Egorushkin 的答案)。 Unfortunately this works with function pointers only and doesn't works (by example) when sync_handler is a lambda.不幸的是,这仅适用于 function 指针,并且当sync_handler是 lambda 时(例如)不起作用。

(3) If you can't modify RegisterCmdHandler() but you can use C++17, you can use std::function deduction guides and call the function as follows (3)如果不能修改RegisterCmdHandler()但是可以使用C++17,可以使用std::function推导指引,调用ZC1C425268E68385D1AB5074C17A94F1

RegisterCmdHandler(1, std::function{SomeHandler}); 

or, maybe better if you have to call it in different places, call it through a converter或者,如果您必须在不同的地方调用它,可能会更好,通过转换器调用它

template <typename F>
auto CallRegisterCH (int cmd_if, F && func)
 { return RegisterCmdHandler(cmd_if, std::function{std::forward<F>(func)}); }

calling it as follows如下调用它

CallRegisterCH(1, SomeHandler);

(4) if you can't modify RegisterCmdHandler() and you have to use C++11 or C++14... well... explicating the template types (4) 如果你不能修改RegisterCmdHandler()并且你必须使用 C++11 或 C++14...好吧...解释模板类型

RegisterCmdHandler<Foo, Bar>(1, SomeHandler); 

seems to me the better way.在我看来是更好的方法。

Other ways you can explicit the std::function其他可以显式std::function的方式

std::function<int(int, Foo const &, Bar &)>  sh{ SomeHandler };

RegisterCmdHandler(1, sh);

but seems to me almost the same thing.但在我看来几乎是一样的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM