Using enable_if to prevent declaration?

Viewed 396

Stroustrup C++ 4th Ed Page 796 states that "If Enable_if’s condition evaluates to false, the whole function declaration of which it is part is completely ignored." and "...we don’t declare anything.".

Does anyone know why the first f0() is being declared? Am I using enable_if correctly?

My goal is to disable one of the declarations. I'm not sure how both f0() can have a return type, as the false version should be missing ::type.

#include <type_traits>
using namespace std;

template<bool B, typename T>
using Enable_if = typename std::enable_if<B,T>::type;

template <class T>
class X {
    Enable_if<false, T> f0(int x) {};
    Enable_if<true, T> f0(int x) {};
};

int main(void)
{
    X<void> xx;
    return 0;
}

Compilation:

clang++ -std=c++11 -Wall -pedantic test197.cc && ./a.out
test197.cc:10:24: error: functions that differ only in their return type cannot
      be overloaded
    Enable_if<true, T> f0(int x) {};
    ~~~~~~~~~~~~~~~~~~ ^
test197.cc:9:25: note: previous definition is here
    Enable_if<false, T> f0(int x) {};
    ~~~~~~~~~~~~~~~~~~~ ^
1 error generated.
1 Answers

You mustn't use this way because your object will be created in any case since the class doesn't have a condition to be created or not. And then here Enable_if<false, T> f0(int x) {};, the condition is false then there is no type. note that template class is instantiated on passing your parameter in the beginning and all that has done is replacing T by void.

one way you can use is as follows

#include <type_traits>
using namespace std;

template<bool B, typename T>
using Enable_if = typename std::enable_if<B,T>::type;


struct X {
    template <class T>
    Enable_if<true, T> f0(int x) {}
    template <class T>
    Enable_if<false, T> f0(int x) {}
};

int main(void)
{
    X xx;
    xx.f0<void>(4);
    return 0;
}

Here we have two function templates, hence each one of them may be instantiated or not and this depends on the condition inside the class. If it's true, the function will be instantiated and vice versa. note that here only the needed function is instantiated.

Related