c++:std::function returns 空指针实例的目标
c++ : target of instance of std::function returns null pointer
编译如下代码:
#include <iostream>
#include <functional>
typedef void (*f_type) (int a);
void say(int a)
{
std::cout << a << "!" << std::endl;
}
int main()
{
int a=5;
say(a);
std::function<void(int)> fn{say};
f_type fn_pointer = fn.target<void(int)>();
if(fn_pointer)
fn_pointer(a);
else
std::cout << "null ptr" << std::endl;
return 0;
}
但执行时打印:
5!
nullptr
我想了解为什么 target 返回一个空指针,而不是指向函数“say”的指针。
注意:它为 c++ 编译到 c++14,对于 c++17 以后,编译失败并出现错误(这对我来说很神秘):
In file included from /usr/include/c++/7/functional:58:0,
from main.cpp:11:
/usr/include/c++/7/bits/std_function.h: In instantiation of ‘_Functor* std::function<_Res(_ArgTypes ...)>::target() [with _Functor = void(int); _Res = void; _ArgTypes = {int}]’:
<span class="error_line" onclick="ide.gotoLine('main.cpp',28)">main.cpp:28:46</span>: required from here
/usr/include/c++/7/bits/std_function.h:733:9: error: invalid use of const_cast with type ‘void (*)(int)’, which is a pointer or reference to a function type
return const_cast<_Functor*>(__func);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
在 VS2017 上重现了它,看起来像 target
方法 returns 一个 指向指针 的指针(如返回指向存储的实际函数指针的指针在对象中),并相应地期望其模板类型参数。这是一个有效的修改示例:
#include <iostream>
#include <functional>
typedef void(*f_type) (int a);
void say(int a)
{
std::cout << a << "!" << std::endl;
}
int main()
{
int a = 5;
say(a);
std::function<void(int)> fn{say};
f_type* fn_pointer = fn.target<void(*)(int)>();
if (fn_pointer)
(*fn_pointer)(a);
else
std::cout << "null ptr" << std::endl;
return 0;
}
确认 target
通过 运行 返回指向实际函数指针的指针:
#include <iostream>
#include <functional>
typedef void(*f_type) (int a);
void say(int a)
{
std::cout << a << "!" << std::endl;
}
void say_boo(int a)
{
std::cout << "booooo" << std::endl;
}
int main()
{
int a = 5;
std::function<void(int)> fn{say};
f_type* fn_pointer = fn.target<void(*)(int)>();
(*fn_pointer)(a);
fn = say_boo;
(*fn_pointer)(a);
return 0;
}
这产生了以下输出:
5!
booooo
编译如下代码:
#include <iostream>
#include <functional>
typedef void (*f_type) (int a);
void say(int a)
{
std::cout << a << "!" << std::endl;
}
int main()
{
int a=5;
say(a);
std::function<void(int)> fn{say};
f_type fn_pointer = fn.target<void(int)>();
if(fn_pointer)
fn_pointer(a);
else
std::cout << "null ptr" << std::endl;
return 0;
}
但执行时打印:
5!
nullptr
我想了解为什么 target 返回一个空指针,而不是指向函数“say”的指针。
注意:它为 c++ 编译到 c++14,对于 c++17 以后,编译失败并出现错误(这对我来说很神秘):
In file included from /usr/include/c++/7/functional:58:0,
from main.cpp:11:
/usr/include/c++/7/bits/std_function.h: In instantiation of ‘_Functor* std::function<_Res(_ArgTypes ...)>::target() [with _Functor = void(int); _Res = void; _ArgTypes = {int}]’:
<span class="error_line" onclick="ide.gotoLine('main.cpp',28)">main.cpp:28:46</span>: required from here
/usr/include/c++/7/bits/std_function.h:733:9: error: invalid use of const_cast with type ‘void (*)(int)’, which is a pointer or reference to a function type
return const_cast<_Functor*>(__func);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
在 VS2017 上重现了它,看起来像 target
方法 returns 一个 指向指针 的指针(如返回指向存储的实际函数指针的指针在对象中),并相应地期望其模板类型参数。这是一个有效的修改示例:
#include <iostream>
#include <functional>
typedef void(*f_type) (int a);
void say(int a)
{
std::cout << a << "!" << std::endl;
}
int main()
{
int a = 5;
say(a);
std::function<void(int)> fn{say};
f_type* fn_pointer = fn.target<void(*)(int)>();
if (fn_pointer)
(*fn_pointer)(a);
else
std::cout << "null ptr" << std::endl;
return 0;
}
确认 target
通过 运行 返回指向实际函数指针的指针:
#include <iostream>
#include <functional>
typedef void(*f_type) (int a);
void say(int a)
{
std::cout << a << "!" << std::endl;
}
void say_boo(int a)
{
std::cout << "booooo" << std::endl;
}
int main()
{
int a = 5;
std::function<void(int)> fn{say};
f_type* fn_pointer = fn.target<void(*)(int)>();
(*fn_pointer)(a);
fn = say_boo;
(*fn_pointer)(a);
return 0;
}
这产生了以下输出:
5!
booooo