下面的SFINAE代码使用可变参数模板很好地编译使用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);
}
我想要正确的重载 foo
根据类型递归调用 H
:
- 如果
std::begin(h)
定义为h
类型H
, 我想要 要选择过载编号1 - 如果
H
是一个“整体类型”,我想要超载2号。
这样可以正常工作。但是,如果我添加另一个重载 枚举 类型(你可以尝试取消注释第三次重载),然后我得到:
错误:只有枚举类型具有基础类型
我同意这一点 枚举 有一个基础类型,因此为什么不是第三个重载(与 std::underlying_type
)让SFINAE-d离开?