构造一个没有默认构造函数的空对象
Construct an empty object without the default constructor
假设我有一个类型F
。我知道 F
是空的,但是 F
没有默认构造函数,所以我不能用 F()
来构造它。无论如何,有没有办法获得 F
类型的有效对象?我似乎记得有人提到过有一种神秘的联合用法。理想情况下,它会 constexpr
友好。
这很有用,因为无捕获 lambda 仅在 C++20 中获得默认构造函数。在 C++17 中,如果我想 "pass a lambda to a template" 并在没有它的实例的情况下调用该 lambda,我需要能够从类型中重建它。
auto const f = [](int x) { return x; };
using F = decltype(f);
static_assert(std::is_empty_v<F>);
static_assert(!std::is_default_constructible_v<F>);
<i>magically-construct-an-F</i>(42);
but F
has no default constructor
如果是这样,那么用户要么明确删除了它,要么因为用户提供了一些其他构造函数而被隐式删除。在任何一种情况下,类型都不是 Trivial。
如果对象是 non-Trivial,则要从现有实例创建 不带 copying/moving 类型的对象,您必须显式调用某种类型的构造函数。这是无可避免的。
即使联合的通用初始序列规则也不允许您创建另一个对象。它只允许访问其他对象的 non-static 数据成员。由于您的对象是空的,因此这对您没有任何价值。
对于您自己的类型,您可以从自身复制或 move-construct 一个对象:F f = f
。这本身不会导致 UB,请参阅 CWG363。
但是,对于 compiler-provided 闭包类型,它不是那么清楚,即使你知道它是空的。
假设我有一个类型F
。我知道 F
是空的,但是 F
没有默认构造函数,所以我不能用 F()
来构造它。无论如何,有没有办法获得 F
类型的有效对象?我似乎记得有人提到过有一种神秘的联合用法。理想情况下,它会 constexpr
友好。
这很有用,因为无捕获 lambda 仅在 C++20 中获得默认构造函数。在 C++17 中,如果我想 "pass a lambda to a template" 并在没有它的实例的情况下调用该 lambda,我需要能够从类型中重建它。
auto const f = [](int x) { return x; };
using F = decltype(f);
static_assert(std::is_empty_v<F>);
static_assert(!std::is_default_constructible_v<F>);
<i>magically-construct-an-F</i>(42);
but
F
has no default constructor
如果是这样,那么用户要么明确删除了它,要么因为用户提供了一些其他构造函数而被隐式删除。在任何一种情况下,类型都不是 Trivial。
如果对象是 non-Trivial,则要从现有实例创建 不带 copying/moving 类型的对象,您必须显式调用某种类型的构造函数。这是无可避免的。
即使联合的通用初始序列规则也不允许您创建另一个对象。它只允许访问其他对象的 non-static 数据成员。由于您的对象是空的,因此这对您没有任何价值。
对于您自己的类型,您可以从自身复制或 move-construct 一个对象:F f = f
。这本身不会导致 UB,请参阅 CWG363。
但是,对于 compiler-provided 闭包类型,它不是那么清楚,即使你知道它是空的。