enable_if<bool b, T=void>
是定义
type=T
如果
b==true
. 所以,
enable_if<b>::type
只有当
B==真
. sfinae声明替换失败不是错误。IMHO
not_disable_if
更合适的名字。
部分专门化是通过模式匹配模板与当前解析的类型来工作的。您不能向其中添加新的模板参数,因为它将与其他内容匹配。
struct foo<H,std::enable_if_t<...,void>>
只匹配
foo<H,void>
如果
...
可从中扣除
H
并评估为
true
.
struct foo<std::enable_if_t<std::is_integral_v<H>,H>>
无法简单地工作,因为无法推断
H
例如,
foo<int>
. 它必须以某种方式推断
enable_if
和
is_integral
看看如果
H=int
,然后它精确地解析为
foo<int>
当然,这在一般情况下是不能做到的。
sfinae只能应用于过载解决期间考虑的部件。第一个参数和您使用的参数是类模板参数,但是正如我上面所述,这将改变它实际匹配的内容。另一个选项是模板参数本身。但是C++不允许用于类专门化的默认模板参数,通常用于此。函数中没有返回值。sfinae不在类体或其基类内使用任何内容。我不认为你想要的是你当前的设置。
我将提供一个轻微的重新设计:
#include <iostream>
#include <type_traits>
// Only specifies behaviour for the head part - one T
// Ts... can be ignored, but are required.
// - I left them because I'm not sure whether you want to use them in the real code.
// - But they are required because `foos` use them as base classes and they must be unique.
template<typename T,bool is_integral,typename...Ts>
struct foo_impl;
template<typename T,typename...Ts>
struct foo_impl<T,true,Ts...>
{
void func() {
std::cout << "Hooray Inegral" << std::endl;
}
};
template<typename T,typename...Ts>
struct foo_impl<T,false,Ts...>
{
void func() {
std::cout << "Hi" << std::endl;
}
};
template<typename T,typename...Ts>
using foo = foo_impl<T,std::is_integral<T>::value,Ts...>;
template<typename...Ts>
struct foos;
template<typename H,typename...Ts>
struct foos<H,Ts...> : private foo<H,Ts...>, public foos<Ts...>
{
using head = foo<H,Ts...>;
using tail = foos<Ts...>;
//Only named differently for clarity, feel free to rename it back to 'func'
void rec_func()
{
//If we inherited from foo<H> so this was only this->foo<H>::func() then
//foos<int,int> would have two foo<int> base classes and this call would be ambigious.
this->head::func();
this->tail::rec_func();
}
};
template<> struct foos<>{
void rec_func(){}
};
int main()
{
foos<int,int,char,double> x;
x.rec_func();
}
这个
foo
只处理一个
T
并且需要专业化。您可以提取
foo<T,false>
和
foo<T,true>
成为一个公共的基类。目前在
福
和
foos
应用程序编程接口。但是
福
API可以被视为私有的,也可以是不同的,所以我不会说这是一个缺点。正如我解释的那样
Ts...
在里面
foo_impl
是必需的。如果你不需要它们,它们可以通过-例如简单地从
std::tuple<foo<Ts>...>
和一些折叠表达式(C++ 17)/魔术(C++ 14)调用
func
功能。如果你愿意的话,我可以补充一下。