函数构造函数和nullptr
std::function constructor and nullptr
为什么下面的代码输出"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 [function .wrap. function .con]
template<class F> function(F f);
template<class F, class A> function(allocator_arg_t, const A& a, F f);
…
8 后置条件:
!*this
:—f
为NULL
函数指针。—f
是指向成员的NULL
指针。—F
为实例函数类模板,!f
我认为这是一个bug。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
求值为true
时,(f == nullptr)
应求值为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
是一个空函数指针,上面的段落应该保证从fp
初始化f
后,表达式!f
的计算结果为true
。这反过来意味着,与nullptr
比较应该返回true
(根据§20.8.11.2.6/1)。
这意味着这是一个bug
不是答案,但有些细节(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
相关文章:
- "error: no matching function for call to"构造函数错误
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 选择要调用的构造函数
- 如何委托派生类使用其父构造函数?
- 构造函数正在调用一个使用当前类类型的函数
- 没有用于初始化C++中的变量模板的匹配构造函数
- 初始化具有非默认构造函数的std::数组项的更好方法
- 当从函数参数中的临时值调用复制构造函数时
- 在c++构造函数中使用随机字符串生成器
- 一对向量构造函数:初始值设定项列表与显式构造
- 从构造函数抛出异常时如何克服内存泄漏
- 我不明白为什么我声明一个空的内部结构并将其传递给构造函数
- 具有显式定义的默认构造函数的 unique_ptr 到 nullptr 错误的类内成员初始值设定项
- 函数构造函数和nullptr
- 如何防止客户端将nullptr传递给构造函数
- "using" (typedef) 指针:它的默认构造函数返回 nullptr?
- 为什么显式构造函数期望 std::shared_ptr 接受 nullptr