禁用模板化类中的函数

Mic*_*son 5 c++ templates

我试图在一个简单的模板类中禁用一些函数.应删除的函数取决于模板参数是否具有某些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会存储一些状态.

更新:我已经使用到目前为止给出的方法创建了适当的示例.答案的复杂程度各不相同,虽然访问者方法是我可能最终使用的方法(因为它最简单),但我的解决方案(最复杂的)是唯一一个实际删除该功能的方法.

Joh*_*åde 4

您可以使用类模板专门化。如果您有多个函数,那么您可以将每个函数移至一个基类,并专门化每个基类。