标签: c++20

标记可能导致构造返回对象异常的函数 `noexcept`

考虑这个函数:

std::vector<unsigned> copy(std::vector<unsigned> const& v) noexcept
{ return v; }

int main()
{
   try {
       (void)copy({1, 2, 3});
   } catch(...) {}
}

Run Code Online (Sandbox Code Playgroud)

返回对象的副本构造可能会抛出。在这种情况下,异常是否会传播给调用者(即它被认为发生在main),从而在处理catch(...)程序中进行处理?或者异常会遇到noexcept并导致调用std::terminate()

C++17/C++20 中关于生命周期规则的变化(标准化 RVO、临时物化、隐式对象创建等)是否相对于标准的先前版本改变了这方面的一些规则?

c++ exception language-lawyer c++17 c++20

21
推荐指数
1
解决办法
731
查看次数

C++20 协程,await_resume、return_value 和 yield_value 的意外重新排序

背景

我有个任务类型既可以co_returnco_yield。在 LLVM 中,任务按预期工作并通过了一些早期测试。在 MSVC 和 GCC 中,代码以相同的方式失败(巧合?)。


简要问题

具有以下测试功能:

Task<int> test_yielding()
{
    co_yield 1;
    co_return 2;
}
Run Code Online (Sandbox Code Playgroud)

从 Task 对象中检索了两个值。

auto a = co_await fn;
auto b = co_await fn;
Run Code Online (Sandbox Code Playgroud)

a 的值预期为 1,b 的值预期为 2。

结果针对 进行测试a + b == 3

上面的测试通过了,但是下面的测试失败了:

auto res = co_await fn + co_await fn
Run Code Online (Sandbox Code Playgroud)

GCC 和 MSVC 的 res 值为 4。两者都是从最终的 co_return 中检索到的。据我了解,第一次和第二次调用的co_await fn顺序应该是 1 和 2。

在 MSVC 和 GCC 中,代码失败,因为它们似乎重新排序await_resumereturn_value …

c++ c++20 c++-coroutine

21
推荐指数
1
解决办法
642
查看次数

三向比较运算符总是有效吗?

Herb Sutter在他的"宇宙飞船"运营商提案(第12.2节,第12页底部)中说:

基于所有内容<=>及其返回类型:此模型具有主要优势,与先前的C++提议和其他语言的功能相比,此提案有一些独特之处:

[...]

(6)效率,包括最终实现用于比较的零开销抽象:绝大多数比较总是单通道.唯一的例外是生成,<=并且>=在支持部分排序​​和相等的类型的情况下.对于<单通是基本实现了零开销的原则,以避免重复平等的比较,如struct Employee { string name; /*more members*/ };在使用的struct Outer { Employeee; /*more members*/ };-今天的对比违反零开销抽象,因为operator<Outer执行冗余相等比较,因为它执行if (e != that.e) return e < that.e;横贯平等前缀 e.name两次(如果名称相同,则遍历Employee两次其他成员的相等前缀),这通常无法优化.正如Kamiński所指出的,零开销抽象是C++的支柱,并且首次实现它的比较是这种设计的一个重要优势<=>.

但他给出了这个例子(第1.4.5节,第6页):

class PersonInFamilyTree { // ...
public:
  std::partial_ordering operator<=>(const PersonInFamilyTree& that) const {
    if (this->is_the_same_person_as ( that)) return partial_ordering::equivalent;
    if (this->is_transitive_child_of( that)) return partial_ordering::less;
    if (that. …
Run Code Online (Sandbox Code Playgroud)

c++ operators spaceship-operator c++20

20
推荐指数
3
解决办法
2064
查看次数

什么特质/概念可以保证memsetting一个对象是明确定义的?

假设我已经定义了一个zero_initialize()函数:

template<class T>
T zero_initialize()
{
    T result;
    std::memset(&result, 0, sizeof(result));
    return result;
}

// usage: auto data = zero_initialize<Data>();
Run Code Online (Sandbox Code Playgroud)

调用zero_initialize()某些类型会导致不确定的行为1,2.我目前正在执行T验证std::is_pod.由于这个特性在C++ 20中被弃用以及概念的出现,我很好奇zero_initialize()应该如何发展.

  1. 什么(最小)特征/概念可以保证memsetting一个对象是明确定义的?
  2. 我应该用std::uninitialized_fill而不是std::memset吗?为什么?
  3. 对于类型子集,此函数是否已被C++初始化语法之一淘汰?或者它将与即将到来的未来C++版本一起使用?

1) 删除班级的所有成员.
2) 在库类(std :: string)上使用memset时,"未定义的行为"是什么原因?[关闭]

c++ metaprogramming sfinae c++14 c++20

20
推荐指数
2
解决办法
959
查看次数

to_address的特定用例

因此,显然C ++ 20正在得到std::to_address

从cppreference页面上,它的用例对我来说似乎并不明确。我们已经有了operator&std::addressof,为什么还需要另一个函数来为其参数提供地址?

c++ address-operator c++20

20
推荐指数
1
解决办法
773
查看次数

C ++ 20:多种类型的概念及其约束,正确的语法?

可以肯定的是c++20,根据即将到来的标准,根据最近的科隆ISO C ++会议的一份Reddit报告,我们将能够指定模板的概念,并且对于每个类/功能模板,我们将能够设置其类型的约束。 。但是,在文档和教程中(例如here),我找不到适用于多类型用例的正确语法。


假设我们有一个多类型的概念:

template<typename T1, typename T2>
concept AreEqComparable = requires(T1 a, T2 b) {
    { a == b } -> bool;
};
Run Code Online (Sandbox Code Playgroud)

假设我想在两个不同类型之间定义一个简单的比较函数。我怎样才能做到这一点?更具体地说,我应该在???下面的代码部分中写什么:

???
bool are_equal(T1 a, T2 b) { return a == b; }
Run Code Online (Sandbox Code Playgroud)

我在这里这里,甚至这里都没有找到关于这个案例的参考。我已经随机尝试过类似的东西:

/* 1 */ template<AreEqComparable T1, T2>
/* 2 */ AreEqComparable<T1, T2>
/* 3 */ template<AreEqComparable<T1, T2>>
Run Code Online (Sandbox Code Playgroud)

但是所有这些都引发语法错误。我认为答案应该在Bjarne Stroustrup的规范 …

c++ templates c++-concepts c++20

20
推荐指数
3
解决办法
1110
查看次数

非模板函数上的约束表达式的意义是什么?

[temp.constr.decl]说我们可以使用约束表达式来约束模板或函数。

声明符[dcl.decl]告诉我们,对于函数,我们可以添加可选的尾随require 子句来约束它,标准草案n4820甚至提供了这些(看似毫无意义的)示例:

void f1(int a) requires true;
auto f2(int a) -> bool requires true;
Run Code Online (Sandbox Code Playgroud)

我知道约束模板或概念很有用,但是我看不到这些约束对非模板函数有何用处。约束非模板函数有什么意义?

c++ language-lawyer c++20

20
推荐指数
2
解决办法
490
查看次数

是POD类型完全等同于琐碎的标准布局类型吗?

在C ++ 20中,不赞成使用POD的概念,因为它是琐碎且标准的布局的无意义的合成特征。但是,C ++ 20草案中的POD定义并不完全是“琐碎的和标准布局”;实际上是:

POD类是既是普通类又是标准布局类的类,并且不具有非POD类类型的非静态数据成员(或其数组)。POD类型是标量类型,POD类,这种类型的数组或这些类型之一的cv限定版本。

换句话说,POD类型不仅是琐碎的而且是标准布局的,而且也是递归的。

该递归需求是否多余?换句话说,如果一个类型既是琐碎的又是标准布局,那么它是否也自动递归地变得琐碎又是标准布局?如果答案为“否”,那么标准布局,琐碎类型却不能成为POD的例子是什么?

c++ language-lawyer standard-layout c++20

20
推荐指数
2
解决办法
229
查看次数

C ++ 20中的指定初始值设定项

我对c ++ 20功能之一(指定的初始化程序)有疑问(有关此功能的更多信息,请点击此处

#include <iostream>

constexpr unsigned DEFAULT_SALARY {10000};

struct Person
{
    std::string name{};
    std::string surname{};
    unsigned age{};
};

struct Employee : Person
{
    unsigned salary{DEFAULT_SALARY};
};

int main()
{
    std::cout << std::boolalpha << std::is_aggregate_v<Person> << '\n'; // true is printed
    std::cout << std::boolalpha << std::is_aggregate_v<Employee> << '\n'; // true is printed

    Person p{.name{"John"}, .surname{"Wick"}, .age{40}}; // it's ok
    Employee e1{.name{"John"}, .surname{"Wick"}, .age{40}, .salary{50000}}; // doesn't compile, WHY ?

    // For e2 compiler prints a warning "missing initializer …
Run Code Online (Sandbox Code Playgroud)

c++ aggregate designated-initializer c++20

20
推荐指数
2
解决办法
442
查看次数

使用 C++20 chrono,如何计算有关日期的各种事实

https://www.timeanddate.com/date/weekday.html计算一年中某一天的各种事实,例如:

https://i.stack.imgur.com/WPWuO.png

给定一个任意日期,如何使用C++20 chrono 规范计算这些数字?

c++ c++-chrono c++20

20
推荐指数
1
解决办法
1557
查看次数