小编fro*_*nca的帖子

在没有 UB 的情况下指示多种类型的非法价值的常用方法

我正在编写某种(开放寻址)哈希表。

对于我希望允许包含在哈希表中的所有有效类型T,我希望该类型有一些非法值来指示表槽为空。

我知道的最简单的解决方案是:

  1. 让桌子成为std::vector<std::optional<T>>
  2. 将该非法值设置为std::nullopt<T>

但我担心可能的开销(因为所有条目都变成std::optional这样)。有没有更快且至少同样安全的方法?

对于T,我将限制设置为:std::is_same_v<std::remove_cvref_t<T>, T>。除此之外没有任何限制。

c++

8
推荐指数
0
解决办法
135
查看次数

C++ 为什么 range::find_if 这么快

我改变了这段代码:

auto it = chunks_.begin();
for (;; ++it) {
  if (it == chunks_.end()) {
    chunks_.emplace_back();
    alloc_chunk_ = &chunks_.back();
    break;
  }
  if (!it->is_filled()) {
    alloc_chunk_ = &*it;
    break;
  }
}
Run Code Online (Sandbox Code Playgroud)

对此:

auto it = std::ranges::find_if(
            chunks_, [](const auto &chunk) { return !chunk.is_filled(); });
if (it == chunks_.end()) {
   chunks_.emplace_back();
   alloc_chunk_ = &chunks_.back();
} else {
   alloc_chunk_ = &*it;
}
Run Code Online (Sandbox Code Playgroud)

在 gcc 11.2 -O3、MSVC 19.32 /Ox 中,第二个版本几乎快了 20 倍。(没有其他代码更改)

chunks_isstd::vector<Chunk>chunks_.size()was 大约为 500,循环执行了大约 100,000 次。第一个代码大约 500ms,第二个代码大约 30ms(包括所有其他代码,所以显然这部分是瓶颈)

这些是 …

c++ compiler-optimization

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

C++23 中 std::string::contains 的时间复杂度是多少?

cppreference 说std::string::contains出来了, https ://en.cppreference.com/w/cpp/string/basic_string/contains

但没有运行时要求。是否保证在线性时间内运行?(比如,在实现中使用 KMP 算法)还是二次时间?

我试图在当前的 C++ 标准草案(http://open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4849.pdf)中找到它,但我找不到参考。

c++ c++23

3
推荐指数
1
解决办法
221
查看次数

strrchr在C++中返回nullptr而不是NULL吗?

我正在将程序从C移植到C++,包括以下代码:

char* get_file_extension(const char* file_name)
{
    char* e = strrchr((char*) file_name, '.');
    if (e == NULL)
    {
        char* buf = strdup(file_name);
        return buf;
    }
    return e + 1;
}
Run Code Online (Sandbox Code Playgroud)

假设我只是将编译器更改为c ++ 11,在这种情况下将NULL更改为nullptr是否足够?目前strrchr来自包含头文件string.h,所以我担心如果strrchr返回NULL而不是nullptr并且if(e == nullptr)检查失败.

或者我应该将string.h更改为cstring

c c++

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

std::optional 的详细程度

这是我的代码中的一个示例,使用std::optional

Max = index(summary_max.value(), clusters[summary_max.value()]->Maximum().value());
Run Code Online (Sandbox Code Playgroud)

在这里,summary_max并且Maximum()std::optional。这太冗长了。我只想打字index(summary_max, clusters[summary_max]->Maximum());

为什么不std::optional<T>支持隐式转换为T?是否有任何有效的、不可避免的理由?

c++ c++17

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

C++ std::fill 与 std::uninitialized_fill

这个问题可能与link重复,但我对这些事情很好奇:

  1. std::fill如果我使用未初始化的原始内存会发生什么坏事?

  2. 关于性能,在已经初始化的内存上使用std::uninitialized_fill(当然,具有相同的对象类型)是否更有利/更有害/与使用相同std::fill

我读了 cppreference 但找不到好的答案

c++

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

如何有条件地获取具有多重继承的多个基类的模板类型

这不是链接的重复项

考虑以下代码:

#include <type_traits>

template <typename... Bases>
struct Overloads : public Bases... {};

template <typename T>
struct A {
  using AType = T;
};

template <typename T>
struct B {
  using BType = T;
};

template <typename T>
struct C {
  using CType = T;
};

template <typename OverloadsType>
struct Derived : public OverloadsType {
  
};

int main() {
    // OK
    static_assert(std::is_same_v<typename Derived<Overloads<A<int>, B<float>, C<char>>>::AType, int>);
    // OK
    static_assert(std::is_same_v<typename Derived<Overloads<A<int>, B<float>, C<char>>>::BType, float>);
    // OK
    static_assert(std::is_same_v<typename Derived<Overloads<A<int>, B<float>, C<char>>>::CType, …
Run Code Online (Sandbox Code Playgroud)

c++ templates template-meta-programming c++17 c++20

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

C 或 C++:如何同时保留“内存中的一个块”?

《算法导论》中有如下练习:

考虑在具有相对少量快速主内存和相对大量较慢磁盘存储的计算机中实现堆栈。PUSH 和 POP 操作适用于单字值。我们希望支持的堆栈可能会变得比内存容量大得多,因此其中大部分必须存储在磁盘上。...

...一个简单但低效的堆栈实现将整个堆栈保留在磁盘上。由于磁盘操作相对昂贵,现在考虑一种堆栈实现,其中我们将堆栈的一页保留在内存中。(我们还维护少量内存来跟踪当前内存中的页面。)仅当相关磁盘页面驻留在内存中时,我们才能执行堆栈操作。如果需要,我们可以将当前内存中的页面写入磁盘,并将新页面从磁盘读入内存。如果相关的磁盘页面已经在内存中,则不需要磁盘访问。...

我想在 C 或 C++ 的实际代码中实现这一点。我知道如何使用mmap()并且可以使用内存映射磁盘文件来实现此目的,但我不知道如何实现“一个堆栈实现,其中我们将堆栈的一页保留在内存中”。有没有办法以 C/C++ 指针的方式逐页管理内存?

c c++ memory-management

0
推荐指数
1
解决办法
99
查看次数