考虑以下简单的协程,它跟踪其构建和销毁:
#include <coroutine>
#include <iostream>
struct simple {
static inline int x = 0;
int id = 0;
simple() : id{ x++ } { std::cout << id << " constructed\n"; }
simple(simple&&) : id{ x++ } { std::cout << id << " move constructed\n"; }
~simple() { std::cout << id << " destructed\n"; }
struct promise_type {
simple get_return_object() { return {}; }
void return_void() {}
void unhandled_exception() { std::terminate(); }
auto initial_suspend() noexcept { return std::suspend_never{}; }
auto final_suspend() …
Run Code Online (Sandbox Code Playgroud) 我遇到了MSVC的一个有趣问题.以下代码无法使用MSVC进行编译:
#include <vector>
#include <unordered_map>
#include <memory>
#include <string>
struct S {
explicit S(const std::string&);
// S(S&&) = default;
std::vector<std::unique_ptr<int>> v;
std::unordered_map<int, int> a;
std::string s;
};
std::vector<S> foo() {
std::vector<S> s;
s.emplace_back("hello");
s.emplace_back("world");
return s;
}
Run Code Online (Sandbox Code Playgroud)
https://www.godbolt.ms/z/pQnKwD
然而,当无论是默认的移动构造函数提供,或者它编译无论是在vector
或unordered_map
已被注释掉.评论这些emplace_back
陈述也"解决"了这个问题.有趣的是,GCC或Clang不会出现这个问题(http://coliru.stacked-crooked.com/a/a4e5590bd63c0de0).
这里发生了什么?
[range.subrange] 中iterator-sentinel-pair
定义的仅展示概念的目的是什么?
template<class T>
concept iterator-sentinel-pair = // exposition only
!range<T> && pair-like<T> &&
sentinel_for<tuple_element_t<1, T>, tuple_element_t<0, T>>;
Run Code Online (Sandbox Code Playgroud)
据我所知,它唯一使用的时间是用于 CTAD,例如在
template<iterator-sentinel-pair P>
subrange(P) -> subrange<tuple_element_t<0, P>, tuple_element_t<1, P>>;
Run Code Online (Sandbox Code Playgroud)
但是,没有任何构造函数std::ranges::subrange
适用于这个概念:唯一可能适合这个参数列表的真正构造函数是这个:
template<not-same-as<subrange> R>
requires borrowed_range<R> &&
convertible-to-non-slicing<iterator_t<R>, I> &&
convertible_to<sentinel_t<R>, S>
constexpr subrange(R&& r) requires (!StoreSize || sized_range<R>);
Run Code Online (Sandbox Code Playgroud)
这需要(通过borrowed_range<R>
)我们拥有range<R>
......但iterator-sentinel-pair
明确要求not range<R>
!
在我看来,目的是允许代码沿着
std::multiset foo = // ...
auto result = foo.equal_range(key); // an iterator-sentinel pair
for (auto value : …
Run Code Online (Sandbox Code Playgroud)