C++模板参数推导失败

C++ template parameter deduction fails

为什么编译器可以用这段代码推导出 T:

#include <vector>

template<typename T>
void foo(T& t) {}

int main(void) {
    std::vector<uint8_t> vec = { 1,2,3 };
    foo(vec);
    return 0;
}

但此代码失败:

#include <vector>
#include <type_traits>

template<typename T>
void foo(typename std::enable_if<true, T>::type& t) {}

int main(void) {
    std::vector<uint8_t> vec = { 1,2,3 };
    foo(vec);
    return 0;
}

我想使用第二个构造,select 在两个模板函数之间,基于传递的 class 方法存在。

在第二种情况下你有一个non-deduced context,换句话说,编译器无法推断类型。

非推导上下文的最简单示例是

template<typename T>
struct Id
{
    using type = T;
};

template<typename T>
void foo(typename Id<T>::type arg); // T cannot be deduced

正如 vsoftco 所解释的,您有一个非推导的上下文。

对于 SFINAE,您可以使用以下之一:

template<typename T>
std::enable_if_t<condition_dependent_of_T, ReturnType>
foo(T& t) {}

template<typename T, std::enable_if_t<condition_dependent_of_T>* = nullptr>
ReturnType foo(T& t) {}

为了使问题形象化,让我们分析一个例子:

template <class>
struct foo { 
    using type = float;
};

template <>
struct foo<bool> {
    using type = int;
};

template <>
struct foo<int> {
    using type = int;
};

template <class T>
void bar(foo<T>::type t) { }

int main() {
   bar(int{}); 
}

现在在行 bar(int{}); 中,类型 bool 以及 int 都与模板参数 T 匹配。那么应该推导出哪一个值呢?这只是为什么非推导上下文是绝对必要的一个例子!