可以使用lambda的类型作为模板参数,例如
template<typename InArg, typename Function>
class selfCompose {
Function f;
public:
selfCompose(Function f): f(f) {}
auto operator() (InArg x) -> decltype(f(f(x))) {
return f(f(x)); }
};
int main() {
auto f = [](int x){return x*x;};
std::cout << selfCompose<int, decltype(f)>(f)(4) // yields (4²)² = 256
<< std::endl;
return 0;
}
但是,重复使用f
是一种冗余。我们可以省略将lambda的类型作为模板传递(将其转换为合适的std::function
(在失去多态性的情况下–但是C lambda无论如何都不是参数多态的)),但是我有一个应用程序,我更希望不必将其值传递给构造函数(因为我想使用我的类的初始化本身作为模板参数,其中需要一个特定的构造函数签名)
template<class InArg, class Function>
class selfCompose {
Function f;
public:
selfCompose() {} // default constructor for f
auto operator() (InArg x) -> decltype(f(f(x))) {
return f(f(x)); }
};
int main() {
auto f = [](int x){return x*x;};
std::cout << selfCompose<int, decltype(f)>()(4) << std::endl;
return 0;
}
但这不会编译,因为lambda有一个已删除的默认构造函数。这对于捕获lambda来说当然是不可避免的,但是对于像我的示例中这样的简单对象,这对我来说没有多大意义:它们不需要引用任何局部变量。
是否有其他方法获得此功能,或者我是否必须将lambda old时髦地定义为命名类?
struct myFun {
auto operator() (int x) -> int {return x*x;}
};
(当然,我想使用的lambda函数没有x那么简单→ x²
,因此仅从几个标准函数类中进行选择是不够灵活的)
本杰明已经为你的案子提出了一个很好的解决办法。你可以用这个。
我的解决方案只是Benjamin答案的一个改进版本,您不必指定lambda参数类型。因此,与其写这封信:
make_selfCompose<int>(f)(4); //Benjamin's solution
你可以这样写:
make_selfCompose(f)(4); //improved - absence `int` template argument.
让make_selfCompose
推导lambda参数类型本身。
对于此解决方案,让我们先编写函数\u traits
类模板,如下所示:
#include <tuple>
template <typename T>
struct function_traits : public function_traits<decltype(&T::operator())>
{};
template <typename C, typename R, typename... A>
struct function_traits<R(C::*)(A...) const>
{
template <size_t i>
struct arg
{
typedef typename std::tuple_element<i, std::tuple<A...>>::type type;
};
};
然后这里是make_selfCompose
的改进版本:
template<typename Fun> //<--- now it has one template parameter
selfCompose<typename function_traits<Fun>::template arg<0>::type, Fun>
make_selfCompose(Fun f)
{
typedef typename function_traits<Fun>::template arg<0>::type InArg; //deduce it
return selfCompose<InArg, decltype(f)>(f);
}
以下是测试程序:
int main() {
auto f = [](int x){return x*x;};
std::cout << make_selfCompose(f)(4) //notice the relief here!
<< std::endl;
return 0;
}
查看在线演示
希望有帮助。:-)
如果将selfCompose
设置为多态,则无需显式传递参数类型或检查存储的函子类型。后者意味着它还能够处理多态函子。
template<typename Functor>
struct self_compose_type {
// Omitting encapsulation for brevity
Functor functor;
// It is possible to overload operator() to deal
// with all cv and ref qualifiers combinations
template<typename... T>
auto operator()(T&&... t)
// Don't use std::result_of for the return type
-> decltype( std::declval<Functor&>()(std::declval<T>()...) )
{ return functor(std::forward<T>(t)...); }
};
template<typename Functor>
self_compose_type<Functor>
self_compose(Functor&& functor)
{ return { std::forward<Functor>(functor) }; }
// C++03 style:
template<typename Functor>
self_compose_type<typename std::decay<Functor>::type>
make_self_compose(Functor&& functor)
{ return { std::forward<Functor>(functor) }; }
无需将运算符()设为变量,如果愿意,可以将其设为只接受一个参数。
您可以遵循像make_pair
和make_shared
这样的函数示例:
template<typename InArg, typename Function>
selfCompose<InArg, Function> make_selfCompose(Function f)
{
return selfCompose<InArg, decltype(f)>(f);
}
int main() {
auto f = [](int x){return x*x;};
std::cout << make_selfCompose<int>(f)(4)
<< std::endl;
return 0;
}
这个问题与前一个问题相关,在前一个问题中,我们注意到init捕获lambdas与Boost的范围和迭代器不兼容,因为一些相当模糊且嵌套很深的故障可能很难通过破解Boost来解决。射程源。 接受的答案建议将lambda存储在对象中。为了避免潜在的函数调用开销,我编写了两个函数对象,可以作为潜在的解决方法。它们在下面的代码中被称为和 不使用和编译行,并正确打印行的的实例。 然而,标准草案提到 5.1.
问题内容: 为什么这段代码会引发SyntaxError? 尽管以下代码段运行时没有可见错误: 问题答案: 必须将所有必需的参数放在任何默认参数之前。仅仅是因为它们是强制性的,而默认参数不是必需的。从语法上讲,如果允许使用混合模式,解释器将 无法 决定哪些值与哪些参数匹配。如果参数的输入顺序不正确,则会引发A : 让我们使用您的函数来查看关键字参数。 假设其允许声明函数如上,然后使用上述声明,我们可
我有一个扩展JTextField的类,我想让CTRL-Shift-O做一些事情。我一直在听 在e.isControlDown()和e.isShiftDown()的帮助下,这种方法运行良好。但我注意到字段中的文本也在从左边向右边移动。显然,这是JTextField的默认行为。所以我在So上找到了这个线程,它似乎很有帮助: 如何禁用JTextField中的默认textfield快捷方式 尽管Syste
这是一个骇人听闻的问题:爱丽丝是一个幼儿园老师。她想给班上的孩子们一些糖果。所有的孩子坐成一行(他们的位置是固定的),每个人根据他(她)在班上的表现有一个评级分数。爱丽丝想给每个孩子至少一颗糖。如果两个孩子挨着坐,那么评分较高的那一个必须得到更多的糖果。爱丽丝想省钱,所以她需要尽量减少给孩子们的糖果总数。 测试数组:n=10,n个元素为[2 4 2 6 1 7 8 9 2 1]。我得到的答案是18
在C#中,当我创建一个空类时,它提供了一个默认的构造函数,但是当我提供一个带有参数的构造函数时,默认的构造函数不再被创建。 我的问题是: 为什么编译器不再给我默认的构造函数呢 这些问题来自于WCF,我需要默认构造函数,但也希望能够为构造函数提供值,并且不必每次都放置默认构造函数,而且我不认为未使用的默认构造函数会使很多开销。
由于找不到文件,send方法返回null BufferedReader。Eclipse只是说有一个NullPointerException是因为print方法,但是当我移除所有try/catch语句时,Eclipse说我需要编写方法抛出IOException或FileNotFoundException,它也允许我这样做,如果我不这样做,它就抛出一个FileNotFoundException。然而,