C 14将具有返回类型可根据返回值推断的函数。
auto function(){
return "hello world";
}
我是否可以将这种行为应用于使用enable_if作为SFINAE按返回类型惯用法的函数?
例如,让我们考虑以下两个函数:
#include <type_traits>
#include <iostream>
//This function is chosen when an integral type is passed in
template<class T >
auto function(T t) -> typename std::enable_if<std::is_integral<T>::value>::type {
std::cout << "integral" << std::endl;
return;
}
//This function is chosen when a floating point type is passed in
template<class T >
auto function(T t) -> typename std::enable_if<std::is_floating_point<T>::value>::type{
std::cout << "floating" << std::endl;
return;
}
int main(){
function(1); //prints "integral"
function(3.14); //prints "floating"
}
如您所见,使用SFINAE by return-type习惯用法选择了正确的函数。然而,这些都是空洞函数。enable_if
的第二个参数默认设置为void
。这是一样的:
//This function is chosen when an integral type is passed in
template<class T >
auto function(T t) -> typename std::enable_if<std::is_integral<T>::value, void>::type {
std::cout << "integral" << std::endl;
return;
}
//This function is chosen when a floating point type is passed in
template<class T >
auto function(T t) -> typename std::enable_if<std::is_floating_point<T>::value, void>::type{
std::cout << "floating" << std::endl;
return;
}
我能对这两个函数做些什么,让它们的返回类型由返回值推断出来吗?
gcc 4.8.2(使用--std=c 1y
)
在@user1508519给出的答案行中,我们可以从方法中删除enable_if参数,并将其保留为模板参数。我们依赖于如果
不需要在方法本身中实际使用这个模板参数!
因此:
template<class T,
typename std::enable_if<std::is_integral<T>::value>::type* dummy = nullptr>
auto function(T t) {
std::cout << "integral" << std::endl;
return 0;
}
// This function is chosen when a floating point type is passed in
template<class T,
typename std::enable_if<std::is_floating_point<T>::value>::type* dummy = nullptr>
auto function(T t) {
std::cout << "floating" << std::endl;
return 0.0f;
}
int main() {
auto ret = function(0); // integral
auto ret2 = function(0.0f); // floating
cout << std::boolalpha;
cout << std::is_integral<decltype(ret)>::value << endl; // true
cout << std::is_floating_point<decltype(ret2)>::value << endl; // true
}
integral
floating
true
true
std::enable_if
可以是返回类型、函数参数或模板参数。如果使用返回类型或模板参数,将出现函数重新定义错误,因此需要使用std::enable_if
作为函数参数:
#include <type_traits>
#include <iostream>
template<class T, typename = typename std::enable_if<std::is_integral<T>::value, void>::type>
auto function(T t, typename std::enable_if<std::is_integral<T>::value, void>::type* dummy = nullptr) {
std::cout << "integral" << std::endl;
return 0;
}
//This function is chosen when a floating point type is passed in
template<class T, typename = typename std::enable_if<std::is_floating_point<T>::value, void>::type>
auto function(T t, typename std::enable_if<std::is_floating_point<T>::value, void>::type* dummy = nullptr) {
std::cout << "floating" << std::endl;
return 0.0f;
}
int main()
{
auto ret = function(0); // integral
auto ret2 = function(0.0f); // floating
std::cout << std::boolalpha << std::is_integral<decltype(ret)>::value << std::endl; // true
std::cout << std::is_floating_point<decltype(ret2)>::value << std::endl; // true
}
std::enable_如果
不必是返回类型,从C 11开始,它可以是模板参数的一部分。
所以你的等价函数可以是(或者,好吧,类似于这个效果的东西):
enum class enabler_t {};
template<typename T>
using EnableIf = typename std::enable_if<T::value, enabler_t>::type;
//This function is chosen when an integral type is passed in
template<class T, EnableIf<std::is_integral<T>>...>
auto function(T t) {
std::cout << "integral" << std::endl;
return;
}
//This function is chosen when a floating point type is passed in
template<class T, EnableIf<std::is_floating_point<T>>...>
auto function(T t) {
std::cout << "floating" << std::endl;
return;
}
它也可以是函数中的参数:
//This function is chosen when an integral type is passed in
template<class T>
auto function(T t, EnableIf<std::is_integral<T>>* = nullptr) {
std::cout << "integral" << std::endl;
return;
}
//This function is chosen when a floating point type is passed in
template<class T>
auto function(T t, EnableIf<std::is_floating_point<T>>* = nullptr) {
std::cout << "floating" << std::endl;
return;
}
这将保持自动类型推演和SFINAE。
我好像不知道我错在哪了。请参阅https://ideone.com/wkszsn 我试图创建一个函数,该函数只有在其参数是某种模板化类时才存在,为迭代器公开一个typedef。 在非条件情况下,函数看起来如下所示: 在本例中,类型扣除对此代码段很有效: 好的。现在我想对参数进行类型推导,并使container类公开typedef迭代器。使用herb sutter gotw sfinae模式,我创建
问题内容: Java通常可以基于参数(甚至与返回类型(例如,与C#相反))来推断泛型。 恰当的例子:我有一个通用类,它只存储一对值,并且可以按以下方式使用: 该方法如下所示: 非常好。但是,这不再适用于以下需要通配符的用例: (请注意显式强制转换以进行正确的类型。) 代码失败,并显示以下错误(由Eclipse提供): 类型不匹配:无法从转换为 但是,显式调用构造函数仍然可以按预期工作: 有人可以解
问题内容: 这是课程: 现在,我试图从类中“反射”此方法: 问题答案: 只有一个。 另一种选择是。 其他原语也是如此。
从JEP 286中,我们可以在JDK 10(18.3)中利用本地类型推断()。JEP声明将进行以下编译,这是预期的: 谢谢!
我正在使用Jooq(与PostgreSQL一起使用)。我需要在一些查询中使用,从自定义类型的字段聚合值。 FIELD2是DB中的列,通常映射为Java Long。 我定义了一个强制转换到某个Java类。 转换在所有查询中都能正常工作,但是当使用时,它会异常失败: 有解决办法吗?这是JOOQ限制吗? 谢谢丹
我正在尝试构建一个通用方法,该方法将调用任何特定于API的endpoint,每个endpoint都返回自己的对象类型。 以上操作不起作用(失败,出现空指针异常) 还尝试了这个: 这失败了: 我已经看到了一种可能的解决方案,通过传入所需类的虚拟对象,但这不是一个理想的选择,因为它需要添加类型参数并向下传递一长串调用。 不知道这将如何工作。