8
There is a technique I sometimes use when overriding template functions that goes like this:
#include <utility>
template<int> struct unique_enum { enum class type {}; };
template<int index> using UniqueEnum = typename unique_enum<index>::type;
template<bool b, int index=1>
using EnableFuncIf = typename std::enable_if< b, UniqueEnum<index> >::type;
template<bool b, int index=1>
using DisableFuncIf = EnableFuncIf<!b, -index>;
// boring traits class:
template<typename T>
struct is_int : std::false_type {};
template<>
struct is_int<int> : std::true_type {};
#include <iostream>
// use empty variardic packs to give these two SFINAE functions different signatures:
template<typename C, EnableFuncIf< is_int<C>::value >...>
void do_stuff() {
std::cout << "int!\n";
}
template<typename C, DisableFuncIf< is_int<C>::value >...>
void do_stuff() {
std::cout << "not int!\n";
}
int main() {
do_stuff<int>();
do_stuff<double>();
}
This distinguishes do_stuff from do_stuff, because one takes 0 or more UniqueEnum<1>s, and the other takes 0 or more UniqueEnum<-1>s. gcc 4.8 considers these different empty packs to be distinct.
However, in the latest version of clang I tried, this fails: it treats the function with 0 UniqueEnum<1>s as being the same as the function with 0 UniqueEnum<-1>s.
There are easy workarounds that work in clang, but I'm wondering if my above technique is legal -- do two function templates, which differ only by empty variardic parameter packs, actually different?