Boost(或其他库)是不是提供了一种将“无构造函数”类的名称提升为使用聚合初始化的函数对象的方法?
Posted
技术标签:
【中文标题】Boost(或其他库)是不是提供了一种将“无构造函数”类的名称提升为使用聚合初始化的函数对象的方法?【英文标题】: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?Boost(或其他库)是否提供了一种将“无构造函数”类的名称提升为使用聚合初始化的函数对象的方法? 【发布时间】:2021-12-27 18:41:12 【问题描述】:这是对this question 的跟进,我在其中询问如何将模板和/或重载函数简洁地转换为函数对象。
接受的答案是你不能没有宏,这是正确的。然后我发现Boost提供了这样一个宏,形式为BOOST_HOF_LIFT
and BOOST_HOF_LIFT_CLASS
macros。
然而,事实证明,还有其他“命名的东西”是你无法传递的。我不知道所有这些,但其中之一是构造函数。 Boost.Hof 提供了一种将它们提升到的方法,通过 boost::hof::construct
。
关键是即使boost::hof::construct
也无法处理没有用户声明的构造函数的类。例如,给定
struct Foo
int foo;
;
调用boost::hof::construct<Foo>()(3)
根本不起作用。 (在Foo
中添加构造函数Foo(int)
使其工作;毕竟这就是boost::hof::construct
的用途。)
当然,在像上面这样简单的情况下,我可以写
auto makeFoo = [](int x) return Foox; ;
但如果我想支持任何类型,我必须处理完美的转发和可变参数。
是否已经有提供此功能的库? It doesn't look like Boost.Hof does...
【问题讨论】:
在这一点上,没有太多理由提供这样的功能。 C++20 允许通过构造函数()
语法进行聚合初始化,所以这样的东西只对 C++20 之前的项目有用。
【参考方案1】:
如果你想要一个函数对象,它在给定一些参数的情况下构造某种类型的对象 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 Tstd::forward<Args>(args)...;
else
return T(std::forward<Args>(args)...);
;
当然,在 C++20 中,您甚至可以对聚合使用 ()
语法。
【讨论】:
我猜boost::hof::construct
没有使用这种技术,因为 Boost.Hof 是一个 C++11/C++14 库,而 std::is_aggregate_v
来自 C++17 (而且,如果我理解正确,它不能用该语言实现,因此需要编译器支持)。以上是关于Boost(或其他库)是不是提供了一种将“无构造函数”类的名称提升为使用聚合初始化的函数对象的方法?的主要内容,如果未能解决你的问题,请参考以下文章
一种将 boost::posix_time::ptime 转换为 __int64 的方法
英特尔 MKL 或一些类似的库是不是提供了一种矢量化方式来计算数组中满足 C 中某些条件的元素数量?