template
在重写函数时,我有时会使用一种技术,如下所示:
#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>();
}
这区别于do_stuff
,do_stuff
因为一个取 0 或多个UniqueEnum<1>
s,而另一个取 0 或多个UniqueEnum<-1>
s。gcc 4.8 认为这些不同的空包是不同的。
但是,在我尝试过的最新版本的 clang 中,这失败了:它将 0 s 的函数视为与 0 UniqueEnum<1>
s 的函数相同UniqueEnum<-1>
。
在clang中有一些简单的解决方法,但我想知道我的上述技术是否合法——做两个函数template
,它们仅通过空的可变参数包不同,实际上不同吗?