PaulProgrammerNoob
PaulProgrammerNoob

Reputation: 654

Specialize template which includes enableif

I want to specialize a templated method. It makes use of std::enable_if to check a static property of the given type:

template <class T, bool fancy= T::IsFancy()>
typename std::enable_if<fancy, void>::type
onlyForFancyGuys(T* component) {
    /*stuff*/
    onlyForFancyGuys(component->parent);
}

As I use this for recursive calls, I need a way to determine, when recursion ends. That is, when type Foo is used. So I tried this specialization.

template<>
typename void onlyForFancyGuys<Foo, true>(Foo* component);

and

template<>
void onlyForFancyGuys<Foo, true>(Foo* component);

But it keeps telling, me that this template-id does not match any template declaration. What am I doing wrong here? Is there something specific with enable_if?

Important fact: Foo does not have the method IsFancy.

Edit: I added IsFancy to Foo, but it does not make any difference.

Edit: I am compiling with MinGW. But I plan to use MSVC, too.

Edit: Adding IsFancy to Foo together with the accepted answer did the trick.

Upvotes: 0

Views: 64

Answers (3)

Jarod42
Jarod42

Reputation: 217085

Just use overload:

void onlyForFancyGuys(Foo* component) { /* ... */ }

template <class T, bool fancy = T::IsFancy()>
typename std::enable_if<fancy, void>::type
onlyForFancyGuys(T* component) {
    /*stuff*/
    onlyForFancyGuys(component->parent);
}

template will be exclude thank to SFINAE (on T::IsFancy())

Upvotes: 2

StPiere
StPiere

Reputation: 4243

I think at some point in the recursion you are reaching the place where no template can be instantiated. Try to declare the general template at the top which breaks the recursion first and then do the rest. There is some weird logic that I don't quite understand but I would try this at least to compile. I think that enable_if is not in the right place in your case. Would tipp at some design issues in general.

template<typename T>
void onlyForFancyGuys(T* t) {
}

and

 template<typename T, bool b>
    void onlyForFancyGuys(T* t) {
    }

And remove typename before void in the specialization, like somebody said.

Upvotes: 0

SoronelHaetir
SoronelHaetir

Reputation: 15164

In:

template<>
typename void onlyForFancyGuys<Foo, true>(Foo* component);

Gid rid tof typename before void.

Upvotes: 1

Related Questions