C++;11带std::函数的类型推断 甚至在阅读了很多在线资源和其他问题之后,我也在努力地在C++中清晰地表达以下内容。我希望避免重复的模板参数,这似乎是不必要的
例如,泛型类型“A”的容器“H”具有泛型类型“B”的泛型方法“M”。这表达了我对“H”和方法“M”的意图:C++;11带std::函数的类型推断 甚至在阅读了很多在线资源和其他问题之后,我也在努力地在C++中清晰地表达以下内容。我希望避免重复的模板参数,这似乎是不必要的,c++,c++11,std,type-deduction,C++,C++11,Std,Type Deduction,例如,泛型类型“A”的容器“H”具有泛型类型“B”的泛型方法“M”。这表达了我对“H”和方法“M”的意图: template<typename A> struct H { explicit H(A x) : x(x) { } A x; template<typename B> H<B> M(std::function<H<B>(A)> g) { return g(x); } }; 模板 结构H { 显
template<typename A>
struct H
{
explicit H(A x) : x(x) { }
A x;
template<typename B>
H<B> M(std::function<H<B>(A)> g) { return g(x); }
};
模板
结构H
{
显式H(ax):x(x){}
A x;
模板
hm(std::函数g){返回g(x);}
};
我的问题是调用“M”需要函数调用和返回容器的重复模板参数。对于“float”类型,这并不太糟糕,但对于其他符号,这很快变得不可管理
// This works but requires the duplicate 'float'
H<int>(1).M<float>([](int x) { return H<float>(x + 3.14); });
// These would be preferred, but neither works
H<int>(1).M<float>([](int x) { return H(x + 3.14); });
H<int>(1).M([](int x) { return H<float>(x + 3.14); });
//这可以工作,但需要重复的“float”
H(1).M([](int x){返回H(x+3.14);});
//这些都是首选,但都不起作用
H(1).M([](int x){返回H(x+3.14);});
H(1).M([](int x){返回H(x+3.14);});
从中,我尝试使用泛型函子类型“F”而不是泛型结果类型来定义“H”:
template<typename A>
struct H2
{
enum { IS_H2 = true };
explicit H2(A x) : x(x) { }
A x;
template<typename F,
class = typename std::enable_if<std::result_of<F(A)>::type::IS_H2>::type>
auto M(F g) -> decltype(g(x)) { return g(x); }
};
模板
结构H2
{
枚举{IS_H2=true};
显式H2(ax):x(x){}
A x;
模板
自动M(F g)->decltype(g(x)){返回g(x);}
};
允许使用所需的语法:
// This now is valid
H2<int>(1).M([](int x) { return H2<float>(x + 3.14); });
// And, as expected, this is not
H2<int>(1).M([](int x) { return x + 3.14; });
//这现在是有效的
H2(1).M([](int x){返回H2(x+3.14);});
//而且,正如预期的那样,这并非如此
H2(1).M([](int x){return x+3.14;});
但我觉得“H2”几乎令人反感,必须有更好的方法
如何更清晰地限制functor的泛型返回类型,或者使std::function使用类型推断?还是我完全从错误的角度来解决这个问题?函数模板就是这样工作的,没有办法解决 如果函数参数中有一个参数,则会执行自动模板参数推断,但这里不是这种情况。例如,编译器可以在此函数中推断类型:
template<typename B>
H<B> M(std::function<H<B>(A)> g, const B&) { return g(x); }
模板
hm(std::函数g,常数B&{返回g(x);}
但是你必须传递一些虚拟值,这(我认为)不是你想要的
以下示例无法将lambda转换为std::function,因为模板参数推导失败:
#include <functional>
template<typename A>
struct H
{
explicit H(A x) : x(x) { }
A x;
template<typename B>
H<B> M(std::function<H<B>(A)> g, const B&) { return g(x); }
};
int main()
{
H<int> h(1);
std::function<H<float>(int)> g( [](int x){ return H<float>(x + 3.14); } );
const auto v = h.M( g, 5.5f );
(void)v;
}
#包括
模板
结构H
{
显式H(ax):x(x){}
A x;
模板
hm(std::函数g,常数B&{返回g(x);}
};
int main()
{
H(1);
函数g([](intx){返回H(x+3.14);});
常数v=h.M(g,5.5f);
(v)无效;
}
你能详细说明你不喜欢的是什么吗H2
?这可能有助于提供替代方案。我还详细说明了M
的声明可能与您的H2
的声明类似。在您的情况下,它可以调整为启用,例如,EnableIf…
。H2不表示方法M的意图,而且我必须明确告诉编译器仅在类型与我期望的匹配时才使用该函数,这让我感到困扰。