Boost(或其他库)是否提供了一种将 "constructor-less" class 的名称提升为使用聚合初始化的函数对象的方法?
Does Boost (or another library) offer a way to lift the name of a "constructor-less" class into a function object that uses aggregate initialization?
这是对 的一种跟进,我在其中询问如何简洁地将模板 and/or 重载函数转换为函数对象。
接受的答案是你离不开宏,这是正确的。然后我发现Boost提供了这样一个宏,形式为BOOST_HOF_LIFT
and BOOST_HOF_LIFT_CLASS
macros.
然而,事实证明,还有其他“命名的东西”是你不能传递的。我不知道所有这些,但其中之一是 constructors。 Boost.Hof 提供了一种将它们提升到 boost::hof::construct
.
的方法
关键是即使 boost::hof::construct
也无法处理没有用户声明的构造函数的 class。例如,给定
struct Foo {
int foo;
};
呼叫boost::hof::construct<Foo>()(3)
根本不起作用。 (在 Foo
中添加构造函数 Foo(int) {}
使其工作;毕竟这就是 boost::hof::construct
的用途。)
当然,在像上面这样的简单情况下,我可以只写
auto makeFoo = [](int x){ return Foo{x}; };
但是如果我想支持任何类型,我必须处理完美转发和可变参数。
是否有图书馆提供此功能? It doesn't look like Boost.Hof does...
如果你想要一个函数对象,它在给定一些参数的情况下构造某种类型 T
的对象,即使 T
是一个聚合,用 C++17 编写也不难:
template<typename T>
struct lifted_construct
{
template<typename ...Args>
T operator() (Args&& ...args)
{
if constexpr(std::is_aggregate_v<T>)
{
return T{std::forward<Args>(args)...};
}
else
{
return T(std::forward<Args>(args)...);
}
}
};
当然,在 C++20 中,您甚至可以对聚合使用 ()
语法。
这是对
接受的答案是你离不开宏,这是正确的。然后我发现Boost提供了这样一个宏,形式为BOOST_HOF_LIFT
and BOOST_HOF_LIFT_CLASS
macros.
然而,事实证明,还有其他“命名的东西”是你不能传递的。我不知道所有这些,但其中之一是 constructors。 Boost.Hof 提供了一种将它们提升到 boost::hof::construct
.
关键是即使 boost::hof::construct
也无法处理没有用户声明的构造函数的 class。例如,给定
struct Foo {
int foo;
};
呼叫boost::hof::construct<Foo>()(3)
根本不起作用。 (在 Foo
中添加构造函数 Foo(int) {}
使其工作;毕竟这就是 boost::hof::construct
的用途。)
当然,在像上面这样的简单情况下,我可以只写
auto makeFoo = [](int x){ return Foo{x}; };
但是如果我想支持任何类型,我必须处理完美转发和可变参数。
是否有图书馆提供此功能? It doesn't look like Boost.Hof does...
如果你想要一个函数对象,它在给定一些参数的情况下构造某种类型 T
的对象,即使 T
是一个聚合,用 C++17 编写也不难:
template<typename T>
struct lifted_construct
{
template<typename ...Args>
T operator() (Args&& ...args)
{
if constexpr(std::is_aggregate_v<T>)
{
return T{std::forward<Args>(args)...};
}
else
{
return T(std::forward<Args>(args)...);
}
}
};
当然,在 C++20 中,您甚至可以对聚合使用 ()
语法。