小编sml*_*mls的帖子

在不违反严格别名的情况下将 `u8string_view` 转换为 `char` 数组?

前提

  • 我在内存中有一个二进制数据块,表示为char*(可能从文件中读取,或通过网络传输)。
  • 我知道它在某个偏移量处包含一个特定长度的 UTF8 编码文本字段。

我如何(安全且可移植地)获得一个u8string_view来表示此文本字段的内容?

动机

将该字段作为 a 传递给下游代码的动机u8string_view是:

  • 它非常清楚地表明文本字段是 UTF8 编码的,与string_view.
  • 它避免了将其作为u8string.

我试过的

这样做的天真方法是:

char* data = ...;
size_t field_offset = ...;
size_t field_length = ...;

char8_t* field_ptr = reinterpret_cast<char8_t*>(data + field_offset);
u8string_view field(field_ptr, field_length);
Run Code Online (Sandbox Code Playgroud)

但是,如果我正确理解 C++ 严格别名规则,这是未定义的行为,因为它char*通过char8_t*返回的指针访问缓冲区的内容reinterpret_cast,而char8_t不是别名类型。

真的吗?

有没有办法安全地做到这一点?

c++ strict-aliasing undefined-behavior c++20

8
推荐指数
1
解决办法
177
查看次数

如何在Perl 6中编写`intersperse`函数

我在Perl 6中遗漏的一件事是像Haskell这样intersperse函数:

intersperse函数接受一个元素和一个列表,并在列表的元素之间"插入"该元素.

例如:

intersperse <X Y>, (<a b>, <c d>, <e f>);
Run Code Online (Sandbox Code Playgroud)

......应该返回这个序列:

<a b>, <X Y>, <c d>, <X Y>, <e f>
Run Code Online (Sandbox Code Playgroud)

所以我一直在尝试将它作为自定义函数实现.为了最大限度地重复使用,它应该:

  1. 支持任何类型的对象(包括List和Nil)作为元素.
  2. 不以任何方式改变元素的容器化.
  3. 不以任何方式压扁或以其他方式影响元件的内部结构.
  4. 如果输入列表作为延迟序列给出,则返回一个惰性序列,以便它可以用于无限序列,如intersperse 42, 1..Inf.

到目前为止我想出的是:

sub intersperse (\element, +list) {
    ((element xx *) Z list).map(|*)[1..*]
}
Run Code Online (Sandbox Code Playgroud)

那就是:无限重复被穿插元件,与列表拉链,然后使用mapslip每个元组,从而不平整原始的元素以去除由拉链进行嵌套加入的层,然后使用数组下标以除去主导重复散布的元素.

它满足要求1-3,但不满足4,因为数组下标急切地操作(即完全迭代输入序列然后返回非惰性列表),因此当给定无限序列时使该函数挂起.

实现此功能以满足所有4个要求的好方法是什么?

list perl6 lazy-sequences

7
推荐指数
1
解决办法
159
查看次数

对任务完成的反应:`.ContinueWith()`vs`GetAwaiter()。OnCompleted()`

假设我有一个Task生成的int,以及一个接受的回调int

Task<int> task = ...;
Action<int> f = ...;
Run Code Online (Sandbox Code Playgroud)

现在,我想对其进行设置,以便一旦任务完成并返回其整数结果,f将使用该整数来调用callfack ,而无需主线程等待任务完成:

  1. 据我了解,典型的解决方案是Task.ContinueWith方法:

    task.ContinueWith(t => f(t.Result));
    
    Run Code Online (Sandbox Code Playgroud)
  2. 但是,也可以TaskAwaiter为任务获取一个,并使用其类似事件的界面:

    TaskAwaiter<int> awaiter = task.GetAwaiter();
    awaiter.OnCompleted(() => f(awaiter.GetResult()));
    
    Run Code Online (Sandbox Code Playgroud)

现在,我意识到这TaskAwaiter并不是应用程序代码中的常用对象,主要存在于内部供await关键字使用。
但是,为了加深我对TPL的理解,我想知道:

解决方案(1)和(2)之间有什么实际区别?

例如,

  • ...关于在哪个线程上调用回调?
  • ...关于在任务或回调中引发异常时会发生什么?
  • ...还有其他副作用吗?

c# continuations task task-parallel-library

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

奇怪的重复模板模式(CRTP)在这里是否是正确的解决方案?

情境

考虑一个类Logger,该类的成员函数write()为标准C ++类型重载,并且还具有一些便捷的函数模板,例如writeLine()在内部调用的模板write()

class Logger {
  public:
    void write(int x) { ... }
    void write(double x) { ... }
    ...

    template <typename T>
    void writeLine(T x) { write(x); ... }
    ...
};
Run Code Online (Sandbox Code Playgroud)

进一步考虑一个子类FooLogger,它write()为特定于域的类型添加了额外的重载(让我们分别调用其中两个FooType1FooType2):

class FooLogger : public Logger {
  public:
    using Logger::write;

    void write(FooType1 x) { ... }
    void write(FooType2 x) { ... }
    ...
};
Run Code Online (Sandbox Code Playgroud)

Ideone上的独立示例程序

问题

FooLogger::write()当直接调用,现在支持其任何参数或者两个类的提供了一种过载。 …

c++ overloading crtp

4
推荐指数
1
解决办法
93
查看次数

如何在对模块进行单元测试时模拟导入的子例程

考虑一个模块,它导出一个连接到Internet并返回结果的子例程:

unit module A;

sub download is export {
     "result from internet"  # Not the actual implementation, obviously.
}
Run Code Online (Sandbox Code Playgroud)

另一个导入并调用该子例程的模块:

use A;  # imports &download into this lexical scope
unit module B;

sub do-something is export {
     download().uc ~ "!!"   # Does something which involves calling &download
}
Run Code Online (Sandbox Code Playgroud)

现在我想为模块编写单元测试B.
但我不希望测试真正连接到互联网; 我希望他们使用download由我的测试脚本控制的子程序的模拟版本:

use Test;
plan 2;

use B;

my $mock-result;
my &mock-download = -> { $mock-result }

# ...Here goes magic code that installs &mock-download
# as …
Run Code Online (Sandbox Code Playgroud)

unit-testing mocking perl6

2
推荐指数
1
解决办法
342
查看次数

多个“const 引用”变量可以共享相同的内存吗?

我想知道在同一范围内有多个“常量引用”变量指向同一个对象是否存在内存成本:

const Animal& animal = getAnimal();
const Dog& dog = static_cast<const Dog&>(animal);
Run Code Online (Sandbox Code Playgroud)

从概念上讲,animaldog是两个变量,每个变量都是指针大小,因此将占用 2 个寄存器(或堆栈上的 2* 指针大小区域)。

但是(假设没有多重继承等),编译器可以知道它们在整个生命周期中都必须保持相同的指针值。

那么,这两个变量能否共享一个寄存器(或堆栈上一个指针大小的区域)?
“可以”,我的意思是:

  • C++ 标准允许吗?
  • 现代编译器会这样做吗?

c++ memory reference compiler-optimization

2
推荐指数
1
解决办法
105
查看次数