poniższy kod SFINAE ze zmiennej liczbie argumentów szablonów kompiluje ładnie użyciu szczęk 3.7.1, C++ 14:SFINAE nie dzieje z std :: underlying_type
#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);
}
chcę poprawnego przeciążenie foo
być nazywany rekursywnie, w oparciu od rodzaju H
:
- jeśli
std::begin(h)
jest zdefiniowany dlah
typuH
, chcę numer przeciążenie 1 do wyboru - jeśli
H
jest „integralną typu” chcę przeciążać numer 2.
Działa to tak jak jest. Ale jeśli dodać kolejny przeciążenie dla wyliczenia typy (można spróbować un-comment trzecim przeciążenia), a następnie uzyskać:
error: only enumeration types have underlying types
zgadzam się, że tylko enums dostał typ podstawowy, a więc dlaczego jest Czy trzecie przeciążenie (z std::underlying_type
) nie odbiera SFINAE-d?
Dlaczego nie można po prostu użyć std :: enable_if ' :: wartość> :: type'? To [kompiluje się dobrze] (http://ideone.com/AeUzi9). Czy jesteś specyficzny dla 'wyliczeń 'z bazowymi typami' uint8_t' tylko? W takim przypadku możesz dodać 1 dodatkowy warunek "sizeof (H) == sizeof (uint8_t)". tj. 'std :: is_enum :: value && (sizeof (H) == sizeof (uint8_t))'. Jest to opisane w powyższym przykładzie ideowym. –
iammilind
@iammilind: dobra rada, dzięki –