小编Rei*_*izo的帖子

提供可选参数的现代 C++ 方法

让我们采用以下函数声明:

void print(SomeType const* i);
Run Code Online (Sandbox Code Playgroud)

在这里,const*参数的性质i暗示了意图,即参数是optional,因为它可能是nullptr。如果这不是故意的,那么参数将只是一个const&. 交流可选的语义当然不是设计指针的初衷,但使用它们来这样做恰好在很长一段时间内都能正常工作。

现在,由于在现代 C++ 中通常不鼓励使用原始指针(并且应该避免使用std::unique_ptrstd::shared_ptr精确指示特定的所有权 -语义),我想知道如何正确指示函数参数的可选 -语义而不传递值,即复制,作为

void print(std::optional<SomeType> i);
Run Code Online (Sandbox Code Playgroud)

会做。

考虑了一段时间后,我想出了使用的想法:

void print(std::optional<SomeType const&> i);
Run Code Online (Sandbox Code Playgroud)

这实际上是最准确的。但事实证明std::optional 不能有引用类型。¹

另外,使用

void print(std::optional<SomeType> const& i);
Run Code Online (Sandbox Code Playgroud)

决不会是最优的,从那时起,我们将要求我们SomeType在向存在std::optional主叫侧的,可能再次(或相当可能)需要复制那里

问题:那么在不复制的情况下允许可选参数的现代方法是什么?在这里使用原始指针在现代 C++ 中仍然是一种合理的方法吗?


¹:具有讽刺意味的是,所描述的为什么std::optional不能有引用类型的原因(关于重新绑定或转发赋值的争议)不适用于const引用的std::optionals的情况,因为它们不能被分配。

c++ pointers optional-parameters optional semantics

33
推荐指数
3
解决办法
2684
查看次数

C++ 协程等待程序中 `await_ready` 有什么好处

在 C++ 协程中,等待者类型(即/的参数类型co_await和返回类型)需要、和三个方法。我知道在协程挂起/恢复的情况下调用1 的顺序。initial_suspendfinal_suspendawait_ready()await_suspend(std::coroutine_handle<...>)await_resume()

\n

但我不清楚要求采用独特await_ready方法的理由是什么。当返回时true, 的调用await_suspend被阻止(并随之完全暂停)。然而,只需true从 中返回即可实现相同的效果await_suspend

\n

这篇博客文章中,作者 David Mazi\xc3\xa8res 说

\n
\n

await_ready是一种优化。如果返回true,则co_await不会暂停该函数。当然,您可以await_suspend通过恢复(或不挂起)当前协程来实现相同的效果,但在调用之前await_suspend,编译器必须将所有状态捆绑到协程句柄引用的堆对象中,这可能会很昂贵。

\n
\n

然而,对我来说,这似乎不是一个有效的论点:(可能是堆)分配的协程状态需要在promise_type::get_return_object()调用之前创建,并且总是被调用,因为promies_type-instance 是协程状态的一部分。因此,无论我们是否调用,句柄引用的协程状态都会被创建await_suspend

\n

回到将我的想法转化为代码的问题:我看不出在哪种情况下重写

\n
struct awaiter\n{\n  bool await_ready() { /* <arbitrary-await-ready-body> */ }\n  void /*| bool*/ await_suspend(std::coroutine_handle<...>) { /* <arbitrary-await-suspend-body> */ …
Run Code Online (Sandbox Code Playgroud)

c++ coroutine async-await c++-coroutine

8
推荐指数
0
解决办法
1428
查看次数

什么时候将局部变量声明为非静态 constexpr 是有益的/必需的?

尽管阅读了一些 StackOverflow 帖子(thisthis)和 cppreference 页面,但我无法弄清楚非静态局部变量与非静态局部变量 相比有何constexpr好处。 static constexpr

我能看到的唯一区别是每个调用都有自己的实例,但由于它是一个constexpr我在这里看不到实际优势(因为,如果我理解正确,这会导致每个实例都是相同且不可变的,使得多个实例只是多余的)。

或者,从另一个角度争论:由于非静态constexpr局部变量在(每次)函数调用时初始化,因此简单局部变量没有任何优势const,尽管它可以用于编译时评估。但是,当编译时评估需要它们时,没有必要将它们设置为非静态的。

所以我的问题是:我的论点有什么缺陷,在什么情况下非静态constexpr局部变量是合理的并且可能是最佳选择?

c++ static compile-time-constant constexpr

6
推荐指数
0
解决办法
478
查看次数

为什么 std::memcpy (作为类型双关的替代方法)不会导致未定义的行为?

sizeof(double) char在寻找将s 组合到 a 的方法时double,我读了几篇文章,std::memcpy推荐使用以下方法:

char bytes[sizeof(double)];
// fill array
double d;
std::memcpy(&d, bytes, sizeof(double));
Run Code Online (Sandbox Code Playgroud)

但是,我想知道为什么进一步使用d可以定义行为。

如果它不是一个double,而是一个复杂的类对象,那么访问它肯定也不会被定义,不是吗?那么,为什么double.

编辑:为了使我的问题清楚,我想指定我的目标:我想找到一种方法将多个chars 组合成 adouble并进一步使用这个 double,而不会导致未定义的行为。我double希望指定 的值。无论如何,我认为这是不可能的,因为标准甚至没有说明任何有关大小的信息,更不用说double. 但是,我要求d一些有效的(即“可访问的”)double值。

c++ undefined-behavior language-lawyer

5
推荐指数
1
解决办法
639
查看次数

对于类模板,std::enable_if 相对于 static_assert 的优势是什么?

我想知道std::enable_ifoverstatic_asserts防止模板实例化的优势。这个答案表明,这std::enable_if允许SFINAE,这在函数模板的情况下是一个令人信服的论点。

然而,这个论点对于类模板(和变量模板)是否合法?据我所知,那里不涉及重载决议,这使得 SFINAE - 再次,据我所知 - 不相关,但我可能是错的。如果是这样,你能举一个例子吗?

如果不是,我认为static_assert在类模板的情况下是给定问题(防止模板实例化)的更好解决方案,因为它可以说更明确、简洁和可读,并允许自定义错误消息。这是正确的还是我错过了 SFINAE 以外的一点?

c++ templates static-assert enable-if class-template

3
推荐指数
1
解决办法
193
查看次数