【问题标题】:How to check whether a function pointer returns bool如何检查函数指针是否返回bool
【发布时间】:2021-03-06 07:17:45
【问题描述】:

我有一个模板类,它以 std::function 作为参数。

在类中,我需要一个返回 bool 的成员函数。

如果 cbFunctionT 返回 bool,函数应该返回它。 如果 cbFunctionT 返回任何其他值(或为 void),则该函数应返回 false。

预计我需要为此使用 std::enable_if。

问题是如何检查 cbFunctionT 是否返回 bool。 在下面的代码中,我使用 std::is_same 作为我要查找的占位符。

template<typename cbFunctionT> 
class CallBack
{
    template<typename T = cbFunctionT
        typename std::enable_if_t<std::is_same<T,bool>::value>* = nullptr>
    bool funct()
    {
        return cbFunctionT();
    }
    
    template<typename T = cbFunctionT>
    bool funct()
    {
        return false;
    }
}

【问题讨论】:

  • 也许将整个模板专门用于std::function&lt;bool (Args...)&gt;
  • 您的意思是完全正确 boolconst bool 可以接受吗? bool&amp; ?可以隐式或显式转换为 bool 的东西?
  • 您的意思是说您想调用类型为cbFunctionTstd::function 成员,可能称为cbFunction?这段代码看起来每次都会返回false,因为它测试cbFunctionTboolbool()false

标签: c++ templates std-function


【解决方案1】:

我觉得写就够了

template<typename T = cbFunctionT>
bool funct()
{
    if constexpr(std::is_same_v<decltype(T()), bool>)
      return T();
    else
      return false;
}

【讨论】:

  • 这不需要是模板函数来编译。 std::enable_if 需要在 OP 的示例中进行专业化,但 if constexpr 可以使用 cbFunctionT 代替 T
  • @parktomatomi:if constexpr 是 C++17 以使代码不那么冗长,但答案的关键部分是 decltype(T())。这也适用于std::enable_if
【解决方案2】:

我的回答冒昧地假设funct 旨在调用cbFunctionT 类型的数据成员,而不是构造类型本身。

如果您能够使用 C++17 或更高版本,

MSalters 的 general 答案(使用 if constexpr)是正确答案。编译器将在编译时评估条件并仅编译所选分支内的内容。这使您可以内联执行以前必须使用 std::enable_if 的事情。

但是,如果您使用的是 C++11 或 C++14,您仍然可以使用通用助手将 enable_if 从您的课程中拉出:

template <bool condition, typename FTrue, typename FFalse, typename... Ts, typename std::enable_if<condition, int>::type = 0>
auto IfConst(FTrue ftrue, FFalse ffalse, Ts&&... ts) -> decltype(ftrue(std::forward<Ts>(ts)...)) {
    return ftrue(std::forward<Ts>(ts)...);
}

template <bool condition, typename FTrue, typename FFalse, typename... Ts, typename std::enable_if<!condition, int>::type = 0>
auto IfConst(FTrue, FFalse ffalse, Ts&&... ts) -> decltype(ffalse(std::forward<Ts>(ts)...)) {
    return ffalse(std::forward<Ts>(ts)...);
}

然后你可以在非模板方法中实现你的目标:

template<typename cbFunctionT> 
class CallBack
{
    cbFunctionT cbFunction;
public:
    CallBack(cbFunctionT cbFunction) : cbFunction(cbFunction) {}
    bool funct() { 
        return IfConst<std::is_same<cbFunctionT, std::function<bool()>>::value>(
            [this]() { return cbFunction && cbFunction(); },
            []() { return false; });
    }
};

演示:https://godbolt.org/z/o544WM

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-30
    • 1970-01-01
    • 1970-01-01
    • 2018-11-11
    • 1970-01-01
    • 2021-06-25
    • 2011-06-07
    相关资源
    最近更新 更多