C++ std::函数构造函数和nullptr
为什么下面的代码将“0”打印为输出C++ std::函数构造函数和nullptr,c++,c++11,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'; } #包括 #包括 int mai
#include <functional>
#include <iostream>
int main()
{
typedef void (*fp_t)();
fp_t fp = nullptr;
std::function<void()> f = fp;
std::cout << (f == nullptr) << '\n';
}
#包括
#包括
int main()
{
typedef void(*fp_t)();
fp_t fp=nullptr;
函数f=fp;
std::cout我认为这是一个bug。根据C++11标准第20.8.11.2.6/1段:
[……]
8后置条件:!*如果以下任一条件成立,则此
:
-f
是一个空函数指针。
[……]
由于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; }
模板
静态布尔
_M_非空函数(常数函数和函数)
{return static_cast(u f);}
模板
静态布尔
_M_not_empty_函数(常数Tp*&常数fp)
{return\uuu fp;}
模板
静态布尔
_M_not_empty_函数(_Tp_类::*const&u mp)
{return\uump;}
模板
静态布尔
_M_not_empty_函数(const _Tp&)
{返回true;}
大概
template<typename _Tp>
static bool
_M_not_empty_function(const _Tp*& __fp)
{ return __fp; }
模板
静态布尔
_M_not_empty_函数(常数Tp*&常数fp)
{return\uuu 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);
}
模板
静态布尔
M_not_empty_函数(常数Tp*&常数fp)
{return\uuu fp;}
int main()
{
typedef void(*fp_t)();
fp_t fp=nullptr;
返回M_not_empty_函数(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
错误:调用'M_not_empty_函数(void(*&))时没有匹配的函数
注:候选人为:
注:模板bool M_not_empty_函数(const _Tp*&)
注意:模板参数扣除/替换失败:
注意:类型“const\u Tp”和“void()”具有不兼容的cv限定符
!*这并不意味着这==nullptr
是真的。一个使用运算符bool
,另一个使用运算符==
。不过,我想说他们应该比较相等。如果nullptr
的相等值为空,则比较true,并且使用空函数指针初始化它会使其为空。@chris:Acco根据20.8.11.2.6/1,f==nullptr
返回!f
。我倾向于认为这是一个bug@AndyProwl,同意。我的第一条评论完全基于调用哪个函数,并且它们不必总是做相同的事情。在std::function
的情况下,结果是它们做了。这太奇怪了……gcc 4.7.2和nd MSVC-11.0给出了output@NikitaTrophimov:是的,确实很奇怪。FWIW,Clang给出了输出Iexpect@NikitaTrophimov:是,在上下文中转换为bool
(将调用std::function
的显式运算符bool()
)@NikitaTrophimov:如果从nullptr
构造,它没有目标,!f
的计算结果为true
。@NikitaTrophimov:我不知道为什么会出现错误,我只知道标准非常清楚行为应该是什么(见答案)。感谢您为我调试了它,我会尽快在GCC中修复它:)
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