Je joue avec des packs de paramètres et j'ai obtenu un comportement que je n'ai pas été en mesure d'expliquer (d'après ce que j'ai compris, il devrait être valide).
J'ai une structure modèle prenant un type et une spécialisation utilisant deux paquets de paramètres ( http://coliru.stacked-crooked.com/a/0cb6c6fef7b09e6f ):
#include <type_traits>
template<class, int> struct dummy{};
template<class...> struct multiple{};
template<class T, class = std::true_type>
struct exactly_one_not_0 : std::false_type {};
template<class...LTs, class...RTs, class T, int V>
struct exactly_one_not_0
<
multiple
<
dummy<LTs, 0>...,
dummy<T, V>,
dummy<RTs, 0>...
>,
std::bool_constant<V>
> : std::true_type
{};
template<class T>
constexpr bool exactly_one_not_0_v = exactly_one_not_0<T>::value;
using d0 = dummy<int,0>;
using d1 = dummy<int,1>;
static_assert(exactly_one_not_0_v<multiple<d1>>);
static_assert(exactly_one_not_0_v<multiple<d1,d0>>);
static_assert(exactly_one_not_0_v<multiple<d0,d1>>);
static_assert(exactly_one_not_0_v<multiple<d0,d1,d0>>);
static_assert(!exactly_one_not_0_v<multiple<>>);
static_assert(!exactly_one_not_0_v<multiple<d0>>);
static_assert(!exactly_one_not_0_v<multiple<d0,d0>>);
static_assert(!exactly_one_not_0_v<multiple<d1,d1>>);
static_assert(!exactly_one_not_0_v<multiple<d0,d1,d1>>);
static_assert(!exactly_one_not_0_v<multiple<d1,d0,d1>>);
static_assert(!exactly_one_not_0_v<multiple<d1,d1,d0>>);
Les quatre premières affirmations échouent. Pourquoi ? La spécialisation devrait être capable d'attraper ces cas.
En comparaison, le code suivant fonctionne comme prévu ( http://coliru.stacked-crooked.com/a/871ee1cc28f5ddc9 ):
#include <iostream>
template<class T>
struct multi_pack
{
static void f() {std::cout << "base case\n";}
};
template<class...Ts1, class...Ts2>
struct multi_pack<std::pair<std::tuple<Ts1...>, std::tuple<Ts2...>>>
{
using T = std::pair<std::tuple<Ts1...>, std::tuple<Ts2...>>;
static void f() {std::cout << "special case\n";}
};
Savez-vous pourquoi le premier exemple échoue et le second fonctionne ?