考虑这个函数:
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、临时物化、隐式对象创建等)是否相对于标准的先前版本改变了这方面的一些规则?
背景
我有个任务类型既可以co_return和co_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_resume,return_value …
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) 假设我已经定义了一个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()应该如何发展.
std::uninitialized_fill而不是std::memset吗?为什么?1) 删除班级的所有成员.
2) 在库类(std :: string)上使用memset时,"未定义的行为"是什么原因?[关闭]
因此,显然C ++ 20正在得到std::to_address。
从cppreference页面上,它的用例对我来说似乎并不明确。我们已经有了operator&和std::addressof,为什么还需要另一个函数来为其参数提供地址?
可以肯定的是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的规范 …
[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 ++ 20中,不赞成使用POD的概念,因为它是琐碎且标准的布局的无意义的合成特征。但是,C ++ 20草案中的POD定义并不完全是“琐碎的和标准布局”;实际上是:
POD类是既是普通类又是标准布局类的类,并且不具有非POD类类型的非静态数据成员(或其数组)。POD类型是标量类型,POD类,这种类型的数组或这些类型之一的cv限定版本。
换句话说,POD类型不仅是琐碎的而且是标准布局的,而且也是递归的。
该递归需求是否多余?换句话说,如果一个类型既是琐碎的又是标准布局,那么它是否也自动递归地变得琐碎又是标准布局?如果答案为“否”,那么标准布局,琐碎类型却不能成为POD的例子是什么?
我对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)