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 中,您甚至可以对聚合使用 () 语法。