【问题标题】:std::bind null function pointerstd::bind 空函数指针
【发布时间】:2015-10-01 10:24:20
【问题描述】:
#include <iostream>
#include <functional>

typedef int(*SumFptr)(int,int);

int main()
{

    SumFptr ptr = nullptr;
    std::function<int(int)> func = std::bind(ptr, std::placeholders::_1, 42);
    std::cout << (func ? "true" : "false") << std::endl;

    return 0;
}

输出为真。

我的期望是错误的,例如std::function{nullptr}。这是一个错误还是正确的行为,我在哪里可以了解它?

【问题讨论】:

    标签: c++ c++11 stdbind


    【解决方案1】:

    std::function 应该如何知道构造它的对象包含空指针?

    就它而言,它有一个可调用对象,它不知道它是一个包含空指针的可调用对象(如果调用它会崩溃)。

    当您构造 std::function{nullptr} 时,它知道它没有可调用对象,并且行为与您调用默认构造函数完全相同。 std::function{ anything_else } 导致它存储 anything_else 并且除非它是空指针(不是包装空指针的对象!)将认为自己有一个目标对象。

    http://en.cppreference.com/w/cpp/utility/functional/function/operator_bool

    std::function::operator bool
    返回值:true 如果*this 存储一个可调用函数目标,则false 否则。

    换句话说,你的程序几乎完全等同于这个:

    #include <iostream>
    #include <functional>
    
    using SumFPtr = int(*)(int,int);
    
    struct BoundFunction {    
        SumFptr fptr;
        int y;
    
        int operator()(int x) const { return fptr(x, y); }
    };
    
    BoundFunction bind(SumFPtr fptr, int y)
    {
        return BoundFunction{fptr, y};
    }
    
    int main()
    {
        std::function<int(int)> func = bind(nullptr, 42);
        std::cout << (func ? "true" : "false") << std::endl;
    }
    

    现在应该很明显,它当然打印了"true",因为std::function 包含一个可调用对象。

    【讨论】:

    • 是的,但是检查绑定参数不是很容易吗?比如:bind(func, ...) { if (!func) save_nullptr_callable() }
    • 理论上是可能的,但std::function 必须知道如何检查。您是否看到标准中规定的类似内容?为什么bind 应该是一个特例,而对于我的BoundFunction 或捕获空函数指针的lambda 来说同样的情况不起作用?
    • 另外,你可能有一些 func 是一个有效的可调用对象,但 !func 是真的,所以你需要更加小心地正确识别空指针。
    猜你喜欢
    • 2012-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-08
    • 1970-01-01
    • 1970-01-01
    • 2012-09-10
    相关资源
    最近更新 更多