Ich habe eine Bibliothek mit mehreren Funktionsobjekten, die abhängig von std::is_integral
. Ich möchte std::is_invocable
zurückgeben, um false
zurückzugeben, wenn die Bedingung fehlschlägt, aber ich möchte auch eine nette static_assert
Fehlermeldung, wenn ein Benutzer versucht, eine Instanz des Funktionsobjekts aufzurufen. Hier ist ein vereinfachtes Beispiel für die Funktionsobjekte, die ich derzeit habe:
Bei einer solchen Implementierung ist std::is_invocable
% std::false_type
wie erwartet, wenn die SFINAE-Bedingung nicht erfüllt ist, aber die Benutzer auf hässliche SFINAE-Fehlermeldungen stoßen, wenn sie versuchen, das Funktionsobjekt mit Parametern aufzurufen, die die SFINAE-Bedingung nicht erfüllen .
Um bessere Fehlermeldungen zu erhalten, habe ich stattdessen folgende Lösung versucht:
%Vor% Mit dieser Implementierung erhalten Benutzer freundliche Fehlermeldungen, wenn die ursprüngliche SFINAE-Bedingung nicht erfüllt ist, aber Ich probierte mehrere Tricks und Variationen mit Was fehlt mir hier? Gibt es eine Möglichkeit, um beide richtig std::is_invocable
ist std::true_type
, wenn gefragt wird, ob eine function
-Instanz mit einem Typ umgehen kann, der std::is_integral
. decltype(auto)
, if constexpr
und anderen Mechanismen, konnte aber keine Klasse bekommen, in der Fehlermeldungen nett waren und wo std::is_invocable
der erwarteten std::false_type
entsprach, wenn gefragt wurde, ob function
könnte mit falschen Typen aufgerufen werden. std::is_invocable
und benutzerfreundliche Fehlermeldungen zu erhalten?
Hier ist ein schrecklicher Weg. Fügen Sie eine Überladung hinzu:
%Vor% Dies erfüllt die Bedingung is_invocable<>
, da die kontrainierte Funktionsvorlage spezialisierter und bevorzugt ist. Wenn die Bedingung erfüllt ist, ist die Funktion aufrufbar, andernfalls wird sie gelöscht.
Dies ist im Fehlerfall ein wenig besser, denn wenn Sie versuchen, es aufzurufen, erhalten Sie:
%Vor%Der Kommentar wird in der Fehlermeldung angezeigt, die einer statischen Asser-Nachricht ähnelt?
Dies ist eine der Motivationen für Concepts. Mit requires
anstelle von enable_if
erhalten wir:
Das ist ... ein bisschen besser, denke ich.
Tags und Links c++ c++17 sfinae static-assert