SFINAE no sucede con std :: subyacente_tipo
Debajo del código SFINAE con plantillas variadas se compila muy bien usando clang 3.7.1, C ++ 14:
#include <array>
#include <iostream>
#include <vector>
#include <cstdint>
enum class Bar : uint8_t {
ay, bee, see
};
struct S {
static void foo() {}
// std::begin(h) is defined for h of type H
template<typename H, typename... T>
static typename std::enable_if<std::is_pointer<decltype(std::begin(std::declval<H>()))*>::value>::type
foo(const H&, T&&... t)
{ std::cout << "container\n"; foo(std::forward<T>(t)...); }
// H is integral
template<typename H, typename... T>
static typename std::enable_if<std::is_integral<typename std::remove_reference<H>::type>::value>::type
foo(const H&, T&&... t)
{ std::cout << "integer\n"; foo(std::forward<T>(t)...); }
// H is an enum with underlying type = uint8_t
/*
template<typename H, typename... T>
static typename std::enable_if<std::is_same<typename std::underlying_type<H>::type,uint8_t>::value>::type
foo(const H&, T&&... t)
{ std::cout << "enum\n"; foo(std::forward<T>(t)...); }
*/
};
int main()
{
S::foo(std::array<int,8>(), 5, 5L, std::vector<int>{}, 5L);
}
Quiero la sobrecarga correcta defoo
ser llamado recursivamente, según el tipoH
:
std::begin(h)
se define para unh
de tipoH
, Quiero que se elija la sobrecarga número 1SiH
es un "tipo integral", quiero la sobrecarga número 2.Esto funciona como es. Pero si agrego otra sobrecarga paraenumeración tipos (puede intentar descomentar la tercera sobrecarga), luego obtengo:
error: solo los tipos de enumeración tienen tipos subyacentes
Acepto que soloenumeraciones tiene un tipo subyacente, de ahí que no sea la tercera sobrecarga (constd::underlying_type
) alejar a SFINAE-d?