为什么编译器可以使用以下代码推导出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;
}
我想使用第二个构造,在两个模板函数之间进行选择,基于传递的类方法存在。
答案 0 :(得分:6)
在第二种情况下,您有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
答案 1 :(得分:4)
正如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) {}
答案 2 :(得分:2)
为了使问题可视化,让我们分析一个例子:
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
匹配。那么应该推导出哪一个值?这只是为什么非推断上下文是绝对必要的一个例子!