Je voudrais passer un pointeur de fonction à partir d'un tableau de pointeurs de fonction comme argument de modèle. Mon code semble se compiler en utilisant MSVC même si Intellisense se plaint que quelque chose ne va pas. Gcc et clang ne parviennent pas à compiler le code.
Prenons l'exemple suivant:
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 compile le code mais Intellisense donne l'erreur suivante:invalid nontype template argument of type "const FunctionPointer"
gcc ne parvient pas à compiler avec le message suivant:
<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
clang ne parvient pas à compiler avec le message suivant:
<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.
Des questions:
Est wrapper_function<functions[0]>();
valide ou non?
Si ce n'est pas le cas, puis-je faire quelque chose pour passer functions[0]
comme argument de modèle wrapper_function
? Mon objectif est de construire un nouveau tableau de pointeurs de fonction au moment de la compilation, avec le contenu { wrapper_function<functions[0]>, ..., wrapper_function<functions[std::size(functions) - 1]> }
.
wrapper_function<decltype(functions[0])>()
ne compile pas.Réponses:
L'expression
wrapper_function<functions[0]>();
est interdite pour les raisons suivantes:Il est interdit d'utiliser des pointeurs comme arguments de modèle non-type autres que ceux du formulaire,
&id
donc, fondamentalement, cela fonctionnerait:et l'extrait suivant ne fonctionnera pas lorsqu'il est compilé avec l'option C ++ 14:
Une fois compilé avec l'option C ++ 17, votre approche et celle ci-dessus fonctionneraient toutes les deux:
Voir en direct
la source
&id
, maisid
est également autorisé pour les fonctions, comme vous le démontrez dans l'exemple et une valeur de pointeur null est explicitement autorisée sous forme d'expression constante.wrapper_function<func>()
cela fonctionnera également.