Bik*_*eev 5 c++ templates c++11
请考虑以下代码:
template <class...>
using void_t = void;
template <class T>
void bar(T){}
template <class T>
void bar(T, void_t<decltype(std::declval<T>().foo())>* = 0) {}
struct A { void foo(); } a;
bar(a); // gives a compiler error on ambiguous call
Run Code Online (Sandbox Code Playgroud)
所以问题是,为什么这些过载模糊不清?为什么第二次重载不被认为是更严格的,比编译器更专业的第二次?
实现此目的的常用方法之一是创建同样专业的模板的分离。
#include <utility>
#include <iostream>
template<class T>
struct has_foo_impl
{
template<class U> static auto test(U* p) -> decltype(p->foo(), void(), std::true_type());
static auto test(...) -> decltype(std::false_type());
using type = decltype(test((T*)nullptr));
};
template<class T> using has_foo = typename has_foo_impl<T>::type;
template <class...>
using void_t = void;
template <class T, std::enable_if_t<not has_foo<T>::value>* = nullptr>
void bar(T){
std::cout << "not me\n";
}
template <class T, std::enable_if_t<has_foo<T>::value>* = nullptr>
void bar(T) {
std::cout << "me\n";
}
struct A { void foo(); } a;
int main()
{
bar(a); // "me"
}
Run Code Online (Sandbox Code Playgroud)