【问题标题】:How to avoid explicit cast with std::bind() temporary objects?如何避免使用 std::bind() 临时对象进行显式强制转换?
【发布时间】:2013-01-15 23:13:30
【问题描述】:

std::bind 的返回类型(有意)未指定。它在 std::function 中可存储

下面的示例程序显示了我必须如何将 std::bind() 返回的临时对象显式转换为 std::function 才能调用 fn1()。

如果 std::bind 的返回类型是已知的,我可以重载回调构造函数,并且不再需要显式转换 std::bind 临时对象。

有什么办法可以避免显式转换?

// g++ -std=c++11 test.cxx
#include <functional>

using std::placeholders::_1;

class A
{
    public:
        void funcA (int x) { }
};

class Callback
{
    public:
        Callback () = default;
        Callback (std::function<void(int)> f) { }
        // Wish we knew the return type of std::bind()
        // Callback (return_type_of_std_bind f) { }
};

void fn0 (std::function<void(int)> f) { }
void fn1 (Callback cb) { }

int main (void)
{
    A a;
    fn0(std::bind(&A::funcA, &a, _1)); // ok
    fn1(std::function<void(int)>(std::bind(&A::funcA, &a, _1))); // ok, but verbose
    fn1(std::bind(&A::funcA, &a, _1)); // concise, but won't compile
}

可能不相关,但我在 Linux 上使用 gcc 4.7.2。

【问题讨论】:

  • 你得到什么编译错误?
  • 不要试图知道什么是(按设计)不应该知道的,不要问这个问题。不要试图知道类型,编写一个不需要知道类型的构造函数......此时您应该考虑“模板”。

标签: c++ stl c++11 std-function stdbind


【解决方案1】:

最好给Callback一个通用的构造函数:

struct Callback
{
    typedef std::function<void(int)> ftype;
    ftype fn_;

    template <typename T,
              typename = typename std::enable_if<std::is_constructible<ftype, T>::value>::type>
    Callback(T && f) : fn_(std::forward<T>(f))
    { }
};

(我添加了第二个默认模板参数,以仅对声明有意义的类型 T 启用此构造函数,以免创建错误的可转换性属性。)请注意此技术如何删除一个隐式的用户定义转换从转换链中,通过为fn_ 调用显式 构造函数。

【讨论】:

  • 并且说的很明显,如果他不希望它作为成员变量,你也可以有一个局部变量。
猜你喜欢
  • 2012-05-30
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-23
  • 2021-11-06
相关资源
最近更新 更多