【问题标题】:Member function template deduction guide or other method to let the compiler know how to call function成员函数模板推导或其他方法让编译器知道如何调用函数
【发布时间】:2019-02-07 11:36:38
【问题描述】:
struct setup_entry 
{
    template< typename T >
    void Disable( bool(*p)(T*) ) { ... }
}

呼叫禁用:

setup_entry X;

Case 1: X.Disable( [](int*)->bool{...} );        //FAIL to deduce T
Case 2: X.Disable<int>( [](int*)->bool{...} );   //OK   to deduce T

我想使用案例 1。(对用户来说更容易)

有什么想法吗?


记录的简化最终解决方案是这样做:

template< typename T >
void Disable( T&& Callback )
{ 
   auto p = +Callback;
   ...
}

【问题讨论】:

  • 与您的问题无关,但我建议不要使用函数指针作为参数。要么使用模板(就像所有标准库一样),要么使用std::function。这样您就可以使用 any 可调用对象(例如 lambdas with 捕获)。顺便说一句,除非您在函数中需要T,否则为函数对象本身使用模板也可以解决您的问题。

标签: c++ c++11 templates lambda c++17


【解决方案1】:

您不能这样做,因为在template argument deduction 中不会考虑隐式转换(从 lambda 到函数指针); T无法推导出来。

类型推导不考虑隐式转换(除了上面列出的类型调整):这是重载解析的工作,稍后会发生。

如果你想坚持自动类型推导,你可以将 lambda 显式转换为函数指针,例如

X.Disable(+[](int*)->bool{...} ); 
//        ^

或者

X.Disable(static_cast<bool(*)(int*)>([](int*)->bool{...}));

【讨论】:

  • 哈,第一个版本简洁又棒!您介意详细说明一元 + 吗?
  • @songyuanyao 一元+的有趣用法!
  • @lubgr & L. F. 见this。
【解决方案2】:

首先你应该知道[](int*) -&gt; bool {...}的类型不是只是bool(int*)或bool(*)(int*);它是一种独特的闭包类型,可转换为bool(*)(int*)。

而且这种类型在这种情况下是不可推演的。

解决方案:显式进行转换。

X.Disable( static_cast<bool(*)(int*)>([](int*) -> bool {...}) );

更好的解决方案:正如@Some programmer dude 所说,使用模板或使用std::function。例如:

template <typename F>
void Disable(F f)
{
    static_assert(std::is_invocable_r_v<bool, F, int*>, "your message here"); // if you want to ensure that the function is actually valid
    // ...
}

或者:

void Disable(std::function<bool(int*)> f) { ... }

【讨论】:

    猜你喜欢
    • 2019-10-29
    • 2013-01-26
    • 1970-01-01
    • 2013-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多