我正在编写某种(开放寻址)哈希表。
对于我希望允许包含在哈希表中的所有有效类型T,我希望该类型有一些非法值来指示表槽为空。
我知道的最简单的解决方案是:
std::vector<std::optional<T>>std::nullopt<T>但我担心可能的开销(因为所有条目都变成std::optional这样)。有没有更快且至少同样安全的方法?
对于T,我将限制设置为:std::is_same_v<std::remove_cvref_t<T>, T>。除此之外没有任何限制。
我改变了这段代码:
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(包括所有其他代码,所以显然这部分是瓶颈)
这些是 …
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++,包括以下代码:
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?
这是我的代码中的一个示例,使用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?是否有任何有效的、不可避免的理由?
这个问题可能与link重复,但我对这些事情很好奇:
std::fill如果我使用未初始化的原始内存会发生什么坏事?
关于性能,在已经初始化的内存上使用std::uninitialized_fill(当然,具有相同的对象类型)是否更有利/更有害/与使用相同std::fill?
我读了 cppreference 但找不到好的答案
这不是链接的重复项
考虑以下代码:
#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) 《算法导论》中有如下练习:
考虑在具有相对少量快速主内存和相对大量较慢磁盘存储的计算机中实现堆栈。PUSH 和 POP 操作适用于单字值。我们希望支持的堆栈可能会变得比内存容量大得多,因此其中大部分必须存储在磁盘上。...
...一个简单但低效的堆栈实现将整个堆栈保留在磁盘上。由于磁盘操作相对昂贵,现在考虑一种堆栈实现,其中我们将堆栈的一页保留在内存中。(我们还维护少量内存来跟踪当前内存中的页面。)仅当相关磁盘页面驻留在内存中时,我们才能执行堆栈操作。如果需要,我们可以将当前内存中的页面写入磁盘,并将新页面从磁盘读入内存。如果相关的磁盘页面已经在内存中,则不需要磁盘访问。...
我想在 C 或 C++ 的实际代码中实现这一点。我知道如何使用mmap()并且可以使用内存映射磁盘文件来实现此目的,但我不知道如何实现“一个堆栈实现,其中我们将堆栈的一页保留在内存中”。有没有办法以 C/C++ 指针的方式逐页管理内存?