此問題僅用於測試目的,僅此而已。將void函數指針指向void(*)(),然後重鑄爲原始類型
我目前正試圖用不同數量的參數存儲函數指針(這些參數可以有不同的類型)。
基本上,我已經編碼下面的代碼段在C++ 11:
#include <functional>
#include <iostream>
void fct(int nb, char c, int nb2, int nb3) {
std::cout << nb << c << nb2 << nb3 << std::endl;
}
template <typename... Args>
void call(void (*f)(), Args... args) {
(reinterpret_cast<void(*)(Args...)>(f))(args...);
}
int main(void) {
call(reinterpret_cast<void(*)()>(&fct), 42, 'c', 19, 94);
}
我轉換void(*)(int, char, int, int)
函數指針爲通用void(*)()
函數指針。然後,通過使用可變參數模板參數,我簡單地將函數指針重新初始化爲其原始類型,並用一些參數調用該函數。
此代碼編譯並運行。大多數時候,它顯示出良好的價值。然而,這段代碼在Mac OS下給我一些Valgrind錯誤(關於未初始化的值),它有時會顯示一些意外的垃圾。
==52187== Conditional jump or move depends on uninitialised value(s)
==52187== at 0x1004E4C3F: _platform_memchr$VARIANT$Haswell (in /usr/lib/system/libsystem_platform.dylib)
==52187== by 0x1002D8B96: __sfvwrite (in /usr/lib/system/libsystem_c.dylib)
==52187== by 0x1002D90AA: fwrite (in /usr/lib/system/libsystem_c.dylib)
==52187== by 0x100025D29: std::__1::__stdoutbuf<char>::overflow(int) (in /usr/lib/libc++.1.dylib)
==52187== by 0x10001B91C: std::__1::basic_streambuf<char, std::__1::char_traits<char> >::xsputn(char const*, long) (in /usr/lib/libc++.1.dylib)
==52187== by 0x10003BDB0: std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> > std::__1::__pad_and_output<char, std::__1::char_traits<char> >(std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> >, char const*, char const*, char const*, std::__1::ios_base&, char) (in /usr/lib/libc++.1.dylib)
==52187== by 0x10003B9A7: std::__1::num_put<char, std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> > >::do_put(std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> >, std::__1::ios_base&, char, long) const (in /usr/lib/libc++.1.dylib)
==52187== by 0x1000217A4: std::__1::basic_ostream<char, std::__1::char_traits<char> >::operator<<(int) (in /usr/lib/libc++.1.dylib)
==52187== by 0x1000011E8: fct(int, char, int, int) (in ./a.out)
==52187== by 0x1000013C2: void call<int, char, int, int>(void (*)(), int, char, int, int) (in ./a.out)
==52187== by 0x100001257: main (in ./a.out)
我覺得這很好奇,因爲當我調用函數時,我已經將函數指針改寫爲原始類型。我認爲它類似於將數據類型轉換爲void*
,然後將其重新轉換爲原始數據類型。
我的代碼有什麼問題?我們不能將指針指向void(*)()
指針的函數指針,然後將此指針重新指向原始函數指針簽名?
如果不是,還有其他方法可以實現嗎?我對std::bind
不感興趣,它不是我想要的。
你的意思是函數指針?不是指向成員函數的指針? – MSalters
我無法重現。這是你的真實的文字測試案例嗎? –
是的,這正是我已經運行的代碼(在macos優勝美地)。而且,如果我用std :: string替換最後一個參數,我得到了垃圾。 –