Saya ingin melewatkan pointer fungsi dari array pointer fungsi sebagai argumen templat. Kode saya tampaknya dikompilasi menggunakan MSVC meskipun Intellisense mengeluh bahwa ada sesuatu yang salah. Baik gcc dan dentang gagal mengkompilasi kode.
Perhatikan contoh berikut:
static void test() {}
using FunctionPointer = void(*)();
static constexpr FunctionPointer functions[] = { test };
template <FunctionPointer function>
static void wrapper_function()
{
function();
}
int main()
{
test(); // OK
functions[0](); // OK
wrapper_function<test>(); // OK
wrapper_function<functions[0]>(); // Error?
}
MSVC mengkompilasi kode tetapi Intellisense memberikan kesalahan berikut:invalid nontype template argument of type "const FunctionPointer"
gcc gagal mengkompilasi dengan pesan berikut:
<source>: In function 'int main()':
<source>:19:33: error: no matching function for call to 'wrapper_function<functions[0]>()'
19 | wrapper_function<functions[0]>(); // Error?
| ^
<source>:8:13: note: candidate: 'template<void (* function)()> void wrapper_function()'
8 | static void wrapper_function()
| ^~~~~~~~~~~~~~~~
<source>:8:13: note: template argument deduction/substitution failed:
<source>:19:30: error: '(FunctionPointer)functions[0]' is not a valid template argument for type 'void (*)()'
19 | wrapper_function<functions[0]>(); // Error?
| ~~~~~~~~~~~^
<source>:19:30: note: it must be the address of a function with external linkage
dentang gagal dikompilasi dengan pesan berikut:
<source>:19:2: error: no matching function for call to 'wrapper_function'
wrapper_function<functions[0]>(); // Error?
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:8:13: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'function'
static void wrapper_function()
^
1 error generated.
Pertanyaan:
Apakah wrapper_function<functions[0]>();
valid atau tidak?
Jika tidak, adakah yang bisa saya lakukan untuk meneruskan functions[0]
sebagai templat argumen wrapper_function
? Tujuan saya adalah untuk membangun array fungsi pointer baru pada waktu kompilasi, dengan konten { wrapper_function<functions[0]>, ..., wrapper_function<functions[std::size(functions) - 1]> }
.
wrapper_function<decltype(functions[0])>()
tidak dikompilasi.Jawaban:
Ekspresi
wrapper_function<functions[0]>();
dilarang karena hal berikut:Dilarang menggunakan pointer sebagai argumen templat non-tipe selain dari bentuk
&id
jadi, pada dasarnya, berikut ini akan berfungsi:dan cuplikan berikut tidak akan berfungsi saat dikompilasi dengan opsi C ++ 14:
Ketika dikompilasi dengan opsi C ++ 17, pendekatan Anda dan yang di atas akan bekerja:
Lihat langsung
sumber
&id
, tetapi jugaid
diizinkan untuk fungsi, karena Anda menunjukkan dalam contoh dan nilai pointer nol secara eksplisit diizinkan dalam bentuk ekspresi konstan.wrapper_function<func>()
juga akan berfungsi.