I'm trying to disable some functions inside a simple template class. The functions that should be removed depend on whether the template argument has certain typedefs.
The example boils down to this:
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();
}
However this gives me a error: no type named ‘Nested’ in ‘struct NoNested’
style error on gcc and clang++ (mind you old versions of both).
Is there an easy way to remove foo
when the typedef T::Nested
does not exit? (Other than template specialization of the Foo<T>
class, as in the real code I have this for about 5 functions with different typedefs.. which would result in 2^5 different specialization )
EDIT: Since there has been some asking for the motivation for wanting to do this: I'd like to create something like acompile time FSM for use in a DSL.
I'd like to be able to do this
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>(); };
};
So that
FSM<StateA>().next().prev().next().next();
compiles, but
FSM<StateA>().next().prev().prev();
fails.
Note that in reality there would be more transition functions than this, the transition functions would actually do something, and the FSM would store some state.
UPDATE: I've created proper examples using the methods that have been given so far. The answers vary in complexity, and while visitors method is the one I'd probably end up using (as it is simplest), my solution (the most complicated) is the only one that actually removes the function.
You can use class template specialization. If you have several functions, then you can move each function to a base class, and specialize each base class.
Try making function foo
template itself. It will compile only when called, so you will get the error only when you will try calling it with NoNested
class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With