std :: function构造函数和nullptr

时间:2013-05-29 20:46:45

标签: c++ c++11

为什么以下代码打印“0”作为输出?

#include <functional>
#include <iostream>

int main()
{
    typedef void (*fp_t)();

    fp_t fp = nullptr;

    std::function<void()> f = fp;
    std::cout << (f == nullptr) << '\n';
}

我用gcc 4.7.2和MSVC-11.0测试了它。

我认为它应该打印“1”,因为标准中引用了以下内容:

ISO / IEC 14882:2011

20.8.11.2.1 function construct / copy / destroy [func.wrap.func.con]

  

template<class F> function(F f);
  template<class F, class A> function(allocator_arg_t, const A& a, F f);

     

...

     

8 后置条件: !*this如果符合以下任何条件: - fNULL   功能指针。 - f是指向成员的NULL指针。 - F是一个实例   函数类模板和!f

2 个答案:

答案 0 :(得分:15)

我认为这是一个错误。根据C ++ 11标准的第20.8.11.2.6 / 1段:

template <class R, class... ArgTypes>
bool operator==(const function<R(ArgTypes...)>& f, nullptr_t) noexcept;

template <class R, class... ArgTypes>
bool operator==(nullptr_t, const function<R(ArgTypes...)>& f) noexcept;
     

1 退货!f

因此,当且仅当(f == nullptr)评估为true时,!f才会评估为true。然后,第20.8.11.2.1 / 8段规定:

template<class F> function(F f);
template <class F, class A> function(allocator_arg_t, const A& a, F f);
     

[...]

     

8 后置条件:!*this如果符合以下任何条件

     
    

- f是一个NULL函数指针。

         

[...]

  

由于fp是一个空函数指针,上面的段落应该保证在从f初始化fp后,表达式!f计算为true 。这反过来意味着与nullptr的比较应该返回true(通过§20.8.11.2.6/ 1)。

这反过来意味着这是一个错误。

答案 1 :(得分:4)

不是答案,但有些细节(gcc)太大而无法发表评论:

使用

检查功能的有效性
template<typename _Signature>
  static bool
  _M_not_empty_function(const function<_Signature>& __f)
  { return static_cast<bool>(__f); }

template<typename _Tp>
  static bool
  _M_not_empty_function(const _Tp*& __fp)
  { return __fp; }

template<typename _Class, typename _Tp>
  static bool
  _M_not_empty_function(_Tp _Class::* const& __mp)
  { return __mp; }

template<typename _Tp>
  static bool
  _M_not_empty_function(const _Tp&)
  { return true; }

可能

template<typename _Tp>
  static bool
  _M_not_empty_function(const _Tp*& __fp)
  { return __fp; }

旨在使用功能指针,而不是它。相反,使用的一般情况可能只适用于功能对象。

template<typename _Tp>
    static bool
    M_not_empty_function(const _Tp*& __fp)
    { return __fp; }

int main()
{
    typedef void (*fp_t)();
    fp_t fp = nullptr;
    return  M_not_empty_function(fp);
}

生成

error: no matching function for call to 'M_not_empty_function(void (*&)())'
note: candidate is:
note: template<class _Tp> bool M_not_empty_function(const _Tp*&)
note:   template argument deduction/substitution failed:
note:   types 'const _Tp' and 'void()' have incompatible cv-qualifiers