Ich möchte einen Funktionszeiger aus einem Array von Funktionszeigern als Vorlagenargument übergeben. Mein Code scheint mit MSVC kompiliert zu werden, obwohl Intellisense sich darüber beschwert, dass etwas nicht stimmt. Sowohl gcc als auch clang können den Code nicht kompilieren.
Betrachten Sie das folgende Beispiel:
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 kompiliert den Code, aber Intellisense gibt den folgenden Fehler aus:invalid nontype template argument of type "const FunctionPointer"
gcc kann nicht mit der folgenden Meldung kompiliert werden:
<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 kann nicht mit der folgenden Meldung kompiliert werden:
<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.
Fragen:
Ist wrapper_function<functions[0]>();
gültig oder nicht?
Wenn nicht, kann ich irgendetwas tun, um es functions[0]
als Vorlagenargument zu übergeben wrapper_function
? Mein Ziel ist es, beim Kompilieren ein neues Array von Funktionszeigern mit dem Inhalt zu erstellen { wrapper_function<functions[0]>, ..., wrapper_function<functions[std::size(functions) - 1]> }
.
wrapper_function<decltype(functions[0])>()
nicht kompiliert.Antworten:
Der Ausdruck
wrapper_function<functions[0]>();
ist aus folgenden Gründen verboten:Es ist verboten, Zeiger als andere Nicht-Typ-Vorlagenargumente als das Formular zu verwenden,
&id
sodass im Grunde Folgendes funktionieren würde:und das folgende Snippet funktioniert nicht, wenn es mit der Option C ++ 14 kompiliert wird:
Wenn Sie mit der Option C ++ 17 kompiliert werden, funktionieren sowohl Ihr als auch der oben beschriebene Ansatz:
siehe Live
quelle
&id
,id
ist nicht nur das Formular , sondern auch Funktionen zulässig, und ein Nullzeigerwert ist in Form eines konstanten Ausdrucks explizit zulässig.wrapper_function<func>()
auch funktioniert.