下面可變參數模板SFINAE代碼編譯很好用鏗鏘3.7.1,C++ 14:SFINAE不是性病發生:: 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);
}
我想要的foo
正確超載遞歸調用,根據在類型H
:
- 如果
std::begin(h)
爲H
類型的h
被定義,我想選擇 的 過載數
- 如果
H
是一個「整體式」,我想超載數2
這工作,因爲它是。但是,如果我添加其他重載枚舉類型(你可以嘗試取消註釋第三過載),然後我得到:
我同意,只有枚舉有一個基本的類型,因此爲什麼是不是第三次超載(使用std::underlying_type
)將SFINAE-d帶走?
你爲什麼不乾脆用'的std :: enable_if <性病:: is_enum ::值> :: type'?它[編譯好](http://ideone.com/AeUzi9)。你是否僅僅具有'uint8_t'的基礎類型的'enum'?在這種情況下,你可以再添加1個'sizeof(H)== sizeof(uint8_t)'的條件。即:'std :: is_enum :: value &&(sizeof(H)== sizeof(uint8_t))''。這在上面的ideone例子中已經介紹過了。 –
iammilind
@iammilind:很好的建議,謝謝 –