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 中某些条件的元素数量?

Boost分类汇总

Jekyll:在另一个帖子中包含一个帖子

如何在 pkg-config 中使用 C++ Boost 库?

boost 库是不是依赖于 std C++ 库?