Je veux pouvoir évaluer si une fonction accepte un argument de type int, et si elle renvoie void. À cette fin, j'ai utilisé std::conjunction
car je pensais qu'il était censé court-circuiter et ne pas évaluer la deuxième expression mal formée au cas où la fonction ne serait pas appelable avec un argument de type int, mais pour une raison quelconque, j'obtiens une erreur du compilateur :
#include <iostream>
#include <type_traits>
template<typename Function>
struct oneArgVoid
{
static constexpr bool value = std::conjunction_v<std::is_invocable<Function, int>, std::is_void<std::invoke_result_t<Function, int>>>;
};
int main()
{
auto l1 = [](auto x) {};
std::cout << oneArgVoid<decltype(l1)>::value << "\n";
auto l2 = [](auto x) {return 1; };
std::cout << oneArgVoid<decltype(l2)>::value << "\n";
auto l3 = [](auto x, auto y) {};
std::cout << oneArgVoid<decltype(l3)>::value << "\n";
return 0;
}
Il convient de noter que si oneArgVoid
n'est pas appelé sur l3
le code se compile. Démonstration en direct : https://godbolt.org/z/8BUfpT
Je n'utilise pas la fonction "boost", je ne peux donc pas l'utiliser. mpl::eval_if
. Mais j'ai pensé que std::conjunction
était censé faire un court-circuit à cet endroit, est-ce que je me trompe ?
Compte tenu de la suggestion de HolyBlackCat, voici quelque chose d'encore plus étrange : https://godbolt.org/z/2SUij-