我试图在一个简单的模板类中禁用一些函数.应删除的函数取决于模板参数是否具有某些typedef.
这个例子归结为:
template<typename T>
struct Foo
{
typename T::Nested foo() { return typename T::Nested(); }
int bar() { return 1; }
};
struct NoNested
{
};
struct WithNested
{
typedef int Nested;
};
int main()
{
Foo<WithNested> fwn;
fwn.foo();
fwn.bar();
Foo<NoNested> fnn;
//fnn.foo();
fnn.bar();
}
Run Code Online (Sandbox Code Playgroud)
然而,这给了我error: no type named ‘Nested’ in ‘struct NoNested’
gcc和clang ++ 的样式错误(请注意两者的旧版本).
foo
当typedef T::Nested
没有退出时,是否有一种简单的方法可以删除?(除了Foo<T>
类的模板特化之外,在实际代码中我有大约5个具有不同typedef的函数...这将导致2 ^ 5个不同的特化)
编辑: 因为有一些人要求这样做的动机:我想创建类似于编译时间FSM的东西,以便在DSL中使用.
我希望能够做到这一点
struct StateA;
struct StateB;
struct StateC;
struct StateA
{
typedef StateB AfterNext;
};
struct StateB
{
typedef StateA AfterPrev;
typedef StateC AfterNext;
};
struct StateC
{
typedef StateB AfterPrev;
};
template<typename T>
struct FSM
{
FSM<typename T::AfterNext> next() { return FSM<T::AfterNext>(); };
FSM<typename T::AfterPrev> prev() { return FSM<T::AfterPrev>(); };
};
Run Code Online (Sandbox Code Playgroud)
以便
FSM<StateA>().next().prev().next().next();
Run Code Online (Sandbox Code Playgroud)
编译但是
FSM<StateA>().next().prev().prev();
Run Code Online (Sandbox Code Playgroud)
失败.
注意,实际上会有比这更多的转换函数,转换函数实际上会做一些事情,而FSM会存储一些状态.
更新:我已经使用到目前为止给出的方法创建了适当的示例.答案的复杂程度各不相同,虽然访问者方法是我可能最终使用的方法(因为它最简单),但我的解决方案(最复杂的)是唯一一个实际删除该功能的方法.