Below SFINAE Code mit variadische Vorlagen schön klappern mit kompiliert 3.7.1, C++ 14:SFINAE geschieht nicht mit 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);
}
Ich möchte die richtige Überlastung der foo
rekursiv aufgerufen werden, basierend von der Art H
:
- wenn
std::begin(h)
für einenh
der Typ definiert istH
möchte ich die Überlastungs Nummer 1 gewählt werden
- wenn
H
„integraler Typ“ ist, möchte ich überlasten Nummer 2.
Dies funktioniert, wie es ist. Aber wenn ich eine weitere Überlastung für Enum Typen hinzufügen (Sie un-Kommentar dritten Überlastung versuchen kann), dann bekomme ich:
error: only enumeration types have underlying types
Ich bin damit einverstanden, dass nur Aufzählungen einen zugrunde liegenden Typ bekam, also warum ist Nicht die dritte Überlast (mit std::underlying_type
) bekommen SFINAE-d weg?
Warum gehst du nicht einfach verwenden 'std :: enable_if :: value> :: Baumuster zur? Es [kompiliert gut] (http://ideone.com/AeUzi9). Sind Sie spezifisch für 'enum' mit nur darunterliegenden Typen von 'uint8_t'? In diesem Fall können Sie eine weitere Bedingung von "sizeof (H) == sizeof (uint8_t)" hinzufügen. h. .. 'std :: is_enum :: Wert && (sizeof (H) == sizeof (uint8_t))'. Das ist im obigen Beispiel von ideone abgedeckt. –
iammilind
@iammilind: guter Rat, danke –