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
匹配。那么应该推导出哪一个值呢?这只是为什么非推导上下文是绝对必要的一个例子!
为什么编译器可以用这段代码推导出 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
匹配。那么应该推导出哪一个值呢?这只是为什么非推导上下文是绝对必要的一个例子!