std::chrono::years (since C++20) duration</*signed integer type of at least 17 bits*/, std::ratio<31556952>>
使用libc++
,似乎std::chrono::years
is的下划线存储是short
有符号的16 位。
std::chrono::years( 30797 ) // yields 32767/01/01
std::chrono::years( 30797 ) + 365d // yields -32768/01/01 apparently UB
Run Code Online (Sandbox Code Playgroud)
cppreference或其他任何内容是否有错别字?
例子:
#include <fmt/format.h>
#include <chrono>
template <>
struct fmt::formatter<std::chrono::year_month_day> {
char presentation = 'F';
constexpr auto parse(format_parse_context& ctx) {
auto it = ctx.begin(), end = ctx.end();
if (it != end && *it == 'F') presentation = *it++;
# …
Run Code Online (Sandbox Code Playgroud) 根据P1236R1,现在整数类型用数字定义,不再用位.
type minimum range exponent N
signed char 8
short 16
int 16
long 32
long long 64
Run Code Online (Sandbox Code Playgroud)
而不是定义标准仍然缺乏的"位"的含义,C++选择不这样做,而是在术语中定义那些类型range exponent
.
为什么?
为什么不依靠"bit"这个词更好?
这个提案中有哪些"不可观察的位"?
P1236R1是C++ 20的一部分
使用分离的分配创建shared_ptr时,必须在C++ 14 ctor和reset成员函数中提供显式删除函数.
using std::string;
using std::shared_ptr;
using std::default_delete;
int arr_size{};
...
auto string_arr_sptr_cpp14 =
shared_ptr<string[]>(new string[arr_size], default_delete<string[]>() );
string_arr_sptr_cpp14.reset(new string[arr_size], default_delete<string[]>() );
// define an explicit deleter,
// or otherwise, "delete ptr;" will internally be used incorrectly!
Run Code Online (Sandbox Code Playgroud)
通过在C++ 17中支持数组特性的shared_ptr,ctor和reset都不再需要那些?
auto string_arr_sptr_cpp17 = shared_ptr<string[]>(new string[arr_size]);
string_arr_sptr_cpp14.reset(new string[arr_size]);
// deduced delete function calls "delete[] ptr;" correctly now?
Run Code Online (Sandbox Code Playgroud) 特定
auto empty_line = [](auto& str){ return str.size() == 0; };
Run Code Online (Sandbox Code Playgroud)
对于那个ranges::getlines
返回拥有 view_facade
其正面迭代器的缓冲区的拥有者的事实.
所以我们有义务在传递算法之前将这种范围变成左值.
auto line_range1 = ranges::getlines(std::cin);
auto iter1 = ranges::find_if_not(line_range1,empty_line);
auto input1 = std::stoi(*iter1);
Run Code Online (Sandbox Code Playgroud)
而且还有一个很酷的保护机制,可以防止所有解除引用迭代器的时间已经被破坏的数据,并使这些尝试编译时错误.
因此,当拥有view_facade
作为rvalue传递给算法时,保护将参与解除引用.
这不会编译.
auto iter2 = ranges::find_if_not(ranges::getlines(std::cin),empty_line);
// at this point the `owning` range destroyed,
// so as the buffer we (should've) hold (before!).
// So this won't compile
// auto input2 = std::stoi(*iter2);
Run Code Online (Sandbox Code Playgroud)
错误为:
<source>:19:29: error: no match for 'operator*' (operand …
Run Code Online (Sandbox Code Playgroud) 假设我们有
cppcoro::generator<int> gen_impl(int in) {
const auto upper = in + 10;
for (; in < upper; ++in)
co_yield in;
}
cppcoro::generator<cppcoro::generator<int>> gen() {
for (int n = 1; n < 100; n += 10)
co_yield gen_impl(n);
}
Run Code Online (Sandbox Code Playgroud)
所以我们可以很好地迭代内部范围
for (auto&& row : gen() ) {
for (auto n : row)
std::cout << n << ' ';
std::cout << '\n';
}
Run Code Online (Sandbox Code Playgroud)
注意:范围是for ref是必需的,因为cppcoro::generator
不允许复制(删除的副本ctor)
打印
1 2 3 4 5 6 7 8 9 10
11 12 13 14 …
Run Code Online (Sandbox Code Playgroud) 尽管如此,人们可以通过提升获得好处.
#include "boost/smart_ptr/make_shared_array.hpp"
auto int_arr_ptr = boost::make_shared<int[]>(100);
Run Code Online (Sandbox Code Playgroud)
我想知道为什么C++ 17标准不提供std::make_shared<T[]>
它提供的shared_ptr::operator[]
?
std::shared_ptr::operator[]
http://en.cppreference.com/w/cpp/memory/shared_ptr/operator_at
std::make_shared
http://en.cppreference.com/w/cpp/memory/shared_ptr/make_shared
std::shared_ptr
支持数组类型(从C++ 17开始),但std::make_shared
不支持.支持此功能boost::make_shared
allocate_shared
和make_shared
数组
http://www.boost.org/doc/libs/release/libs/smart_ptr/make_shared_array.html
#include <array>
using std::array;
constexpr auto d1=2;
constexpr auto d2=3;
constexpr auto d3=4;
// stacked std::array
using arr_t = array<int,d1>;
using arr2d_t = array<arr_t,d2>;
using arr3d_t = array<arr2d_t,d3>;
constexpr arr3d_t arr1 = {{
{{ {1,2}, {3,4}, {5,6} }},
{{ {1,2}, {3,4}, {5,6} }},
{{ {1,2}, {3,4}, {5,6} }},
{{ {1,2}, {3,4}, {5,6} }}
}};
// built-in array
using carr3d_t = int[d3][d2][d1];
constexpr carr3d_t arr2 = {
{ {1,2}, {3,4}, {5,6} },
{ {1,2}, {3,4}, {5,6} },
{ {1,2}, {3,4}, {5,6} …
Run Code Online (Sandbox Code Playgroud) reinterpret_cast
afloat*
到 a__m256*
并float
通过不同的指针类型访问对象是否合法?
constexpr size_t _m256_float_step_sz = sizeof(__m256) / sizeof(float);
alignas(__m256) float stack_store[100 * _m256_float_step_sz ]{};
__m256& hwvec1 = *reinterpret_cast<__m256*>(&stack_store[0 * _m256_float_step_sz]);
using arr_t = float[_m256_float_step_sz];
arr_t& arr1 = *reinterpret_cast<float(*)[_m256_float_step_sz]>(&hwvec1);
Run Code Online (Sandbox Code Playgroud)
做hwvec1
和arr1
依赖undefined behavior
s 吗?
它们是否违反了严格的别名规则?[基本.lval]/11
或者只有一种定义的内在方式:
__m256 hwvec2 = _mm256_load_ps(&stack_store[0 * _m256_float_step_sz]);
_mm256_store_ps(&stack_store[1 * _m256_float_step_sz], hwvec2);
Run Code Online (Sandbox Code Playgroud)
我注意到英特尔Tremont有 64 字节的存储指令,带有MOVDIRI
和MOVDIR64B
。
这些保证原子写入内存,而不保证加载原子性。此外,写入是弱排序的,可能需要紧跟其后的防护。
我MOVDIRx
在 IceLake 中找不到。
为什么冰湖不需要这样的指令MOVDIRx
?
(在第 15 页底部)
英特尔® 架构指令集扩展和未来功能编程参考
https://software.intel.com/sites/default/files/managed/c5/15/architecture-instruction-set-extensions-programming-reference .pdf#page=15
假设我们有一些相同的汇编的重复,其中包含RDTSC
诸如
volatile size_t tick1;
asm ( "rdtsc\n" // Returns the time in EDX:EAX.
"shl $32, %%rdx\n" // Shift the upper bits left.
"or %%rdx, %q0" // 'Or' in the lower bits.
: "=a" (tick1)
:
: "rdx");
this_thread::sleep_for(1s);
volatile size_t tick2;
asm ( "rdtsc\n" // clang's optimizer just thinks this asm yields
"shl $32, %%rdx\n" // the same bits as above, so it just loads
"or %%rdx, %q0" // the result to qword ptr [rsp + 8]
: …
Run Code Online (Sandbox Code Playgroud)