我的 C++ 程序使用不同宽度的无符号整数来表达对可以表示哪些数据的约束。例如,我有一个大小为 a 的文件uint64_t,我希望使用大小为 a 的缓冲区分块读取它size_t。块是缓冲区大小和(剩余)文件大小中较小的一个:
uint64_t file_size = ...;
size_t buffer_size = ...;
size_t chunk_size = std::min(buffer_size, file_size);
Run Code Online (Sandbox Code Playgroud)
但这失败了,因为std::min要求两个参数具有相同的类型,所以我必须先上后退:
size_t chunk_size = \
static_cast<size_t>(std::min(static_cast<uint64_t>)buffer_size, \
file_size));
Run Code Online (Sandbox Code Playgroud)
这种转换应该是不必要的,因为很明显,它min(size_t, uint64_t)总是适合size_t.
我如何编写一个通用min函数,它采用两种(可能不同的)无符号类型,并且其返回类型是这两种类型中较小的一种?
我想使用https://research.swtch.com/sparse中描述的技巧在C++中构建一个密集的整数集.这种方法通过允许自己读取未初始化的内存来实现良好的性能.
如何在不触发未定义行为的情况下实现此数据结构,并且不会与Valgrand或ASAN等工具发生冲突?
编辑:似乎响应者正在关注"未初始化"这个词,并在语言标准的上下文中对其进行解释.对我而言,这可能是一个糟糕的词语选择 - 这里"未初始化"仅意味着它的价值对于算法的正确运行并不重要.显然可以安全地实现这个数据结构(LLVM在SparseMultiSet中实现它).我的问题是,最好和最有效的方法是什么?
我有以下 Rust 代码(rustc 1.75.0),它“强制”发送一个类型:
struct ForceSend<T>(T);
unsafe impl<T> Send for ForceSend<T> {}
pub fn perform<T>(t: T) {
let wrapped = ForceSend(t);
takes_send(move || {
wrapped.0;
});
}
fn takes_send<F: Send>(_: F) {}
Run Code Online (Sandbox Code Playgroud)
我希望这段代码能够编译,因为闭包通过移动捕获单个值wrapped,并且该值是 Send。根据文档:
如果非唯一不可变引用捕获的所有变量都是同步的,并且唯一不可变或可变引用、复制或移动捕获的所有值都是发送,则闭包为发送。
然而,这无法编译,报告关闭不是发送。
为什么这不能编译?谢谢你的帮助!
这在clang和gcc中没有警告地编译:
const char *foo = "\%";
Run Code Online (Sandbox Code Playgroud)
结果字符串与"%".
这个逃脱是什么?我在哪里可以找到完整的逃生清单?
我想也许是为了逃避有向图,但其他有向字符会产生警告(例如"\:").
谢谢你的帮助!
说我有一个std::set<std::string>,我想知道它是否包含字符串"name":
#include <string>
#include <set>
using namespace std;
bool has_name(const set<string> &s) {
return s.find("name") != s.end();
}
Run Code Online (Sandbox Code Playgroud)
上面的函数构造并销毁一个值为"name"的临时std :: string.这种低效率似乎是不必要的,因为std :: string具有直接与const char*进行比较的功能.我想消除这个暂时的.
我尝试使用带有重载的自定义比较器:
struct str_comp_t {
bool operator()(const string &s1, const char *s2) const {
return s1.compare(s2) < 0;
}
bool operator()(const string &s1, const string &s2) const {
return s1.compare(s2) < 0;
}
};
typedef std::set<string, str_comp_t> string_set_t;
bool has_name_2(const string_set_t &s) {
return s.find("name") != s.end();
}
Run Code Online (Sandbox Code Playgroud)
但是只调用带有std :: string的变体; const char*被忽略.
如何使这个集合直接与常量字符串进行比较,而不是构造一个中间字符串?
计算数组最大值的"JavaScriptonic"方法是:
Math.max.apply(null, array)
Run Code Online (Sandbox Code Playgroud)
但是,在大小为2 ^ 16(Chrome,Safari)或2 ^ 18(Firefox)的阵列上出现"超出最大调用堆栈大小"的错误.见https://jsfiddle.net/dxcot206/
我怎样才能安全地使用这种技术?是否有最大的阵列长度可以保证这种技术有效?
在WebWorker中,答案可能会有所不同,因为后台线程通常具有较小的堆栈大小?
我想从原子 uint32s 拼凑一个 uint64 原子计数器。计数器有一个写入器和多个读取器。编写器是一个信号处理程序,所以它不能阻塞。
我的想法是使用低位的代数作为读锁。读取器重试,直到整个读取过程中生成计数稳定,并且低位未设置。
以下代码在内存排序的设计和使用中是否正确?有没有更好的办法?
using namespace std;
class counter {
atomic<uint32_t> lo_{};
atomic<uint32_t> hi_{};
atomic<uint32_t> gen_{};
uint64_t read() const {
auto acquire = memory_order_acquire;
uint32_t lo, hi, gen1, gen2;
do {
gen1 = gen_.load(acquire);
lo = lo_.load(acquire);
hi = hi_.load(acquire);
gen2 = gen_.load(acquire);
} while (gen1 != gen2 || (gen1 & 1));
return (uint64_t(hi) << 32) | lo;
}
void increment() {
auto release = memory_order_release;
gen_.fetch_add(1, release);
uint32_t newlo = 1 + lo_.fetch_add(1, release);
if (newlo …Run Code Online (Sandbox Code Playgroud) 我想创建一个包装 libcsem_post和sem_wait函数的 Rust 信号量,它们都采用可变int *参数。这要求服务员和海报同时拥有一个指向同一个 int 的可变指针。我该如何安排而不冒 UB 的风险?
我的一个想法是使用UnsafeCell:
use libc;
use std::cell::UnsafeCell;
pub struct Sema {
sema: UnsafeCell<i32>,
}
impl Sema {
pub fn post(&self) {
unsafe { libc::sem_post(self.sema.get()) };
}
pub fn wait(&self) {
unsafe { libc::sem_wait(self.sema.get()) };
}
}
Run Code Online (Sandbox Code Playgroud)
这安全吗?有更好的方法吗?谢谢你的帮助!