小编use*_*932的帖子

C++ 模拟 Rust 类似同步

正如我在一些关于 rust 的视频中看到的那样,它有这样的东西(我使用 c++ 而不是 rust 来展示想法):

template<typename T>
class Synchronized {
    public:
        Synchronized(T);
        Something<T> get();
    private:
        std::mutex lock_;
};
Run Code Online (Sandbox Code Playgroud)

和这样的用法:

Synchronized<std::string> obj;

auto s = obj.get();
//after that you can work with s as with std::string
//and obj.lock_ in locked state, after s was destroyed
//obj.lock_ will be unlocked
Run Code Online (Sandbox Code Playgroud)

boost或其他一些C ++通俗图书馆都有这样的模式实现?

c++ boost c++11

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

c ++足够大的枚举

我有一个很老的风格enum而不是c ++ 11强类型枚举,我想迭代它的值,如下所示:

enum Enum {
  enBEGIN = 0,
  eFirst,
  eSecond,
  //many lines
  enEND
};

Enum val;
for (auto i = make_big_enough_integer<Enum>(val); i != enEND; ++i)
  ;
Run Code Online (Sandbox Code Playgroud)

问题是如何以make_big_enough_integer 最简单的方式实施?

make_big_enough_integer应该返回val转换为整数类型int32_t,uint32_t或者uint64_t可以处理所有值enum.

注意1:转换为强类型枚举不是一个选项,因为它在程序的太多地方使用,并且无法想象可以替换其所有出现的正则表达式.

注意2:我可以在循环之前插入,类似这样static_cast(sizeof(Enum) <= sizeof(int), "error"); 或者只是使用uint64_t,但我有兴趣将自动采用写入平台代码.

c++ enums c++11

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

repr(C)类型如何处理Option?

我有这个C代码:

typedef void (*f_t)(int a);

struct Foo {
        f_t f;
};

extern void f(struct Foo *);
Run Code Online (Sandbox Code Playgroud)

bindgen生成以下Rust代码(我删除了不重要的细节):

#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct Foo {
    pub f: ::std::option::Option<extern "C" fn(a: ::std::os::raw::c_int)>,
}
Run Code Online (Sandbox Code Playgroud)

我不明白为什么Option在这里.显然Rust enum和C指针在位级别上是不一样的,所以Rust编译器如何处理这个?

当我调用C f函数并将指针传递给Rust结构时Foo,编译器是否转换Foo_rustFoo_C然后仅将指针传递Foo_Cf

rust

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

Vec &lt;PathBuf&gt;到&[&Path]没有分配吗?

我有返回的Vec<PathBuf>函数和接受的函数&[&Path],基本上是这样的:

use std::path::{Path, PathBuf};

fn f(paths: &[&Path]) {
}

fn main() {
    let a: Vec<PathBuf> = vec![PathBuf::from("/tmp/a.txt"), PathBuf::from("/tmp/b.txt")];

    f(&a[..]);
}
Run Code Online (Sandbox Code Playgroud)

是否可以在没有内存分配的情况下转换Vec<PathBuf>&[&Path]

如果不是,我应该如何更改f签名以接受带有Path和的切片PathBuf

reference slice rust

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

对模式的引用匹配或取消引用的值之间有什么区别吗?

Clippy警告这样的代码:

fn func<T>(data: &Option<T>) {
    if let &Some(ref value) = data {}
}
Run Code Online (Sandbox Code Playgroud)
warning: you don't need to add `&` to all patterns
 --> src/main.rs:2:5
  |
2 |     if let &Some(ref value) = data {}
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: #[warn(match_ref_pats)] on by default
  = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.210/index.html#match_ref_pats
help: instead of prefixing all patterns with `&`, you can dereference the expression
  |
2 |     if let Some(ref value) = *data {}
  |            ^^^^^^^^^^^^^^^   ^^^^^
Run Code Online (Sandbox Code Playgroud)

从编译器的角度来看,这些构造是否相同:

if …
Run Code Online (Sandbox Code Playgroud)

rust

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

将类型作为标识传递给 macro_rules 时,“没有规则需要令牌`&lt;`”

玩具示例:

macro_rules! boo {
    ($T:ident) => {
        let x: $T;
    };
}

fn main() {
    boo!(i32);         // WORKS
    boo!(Option<i32>); // PROBLEM
}
Run Code Online (Sandbox Code Playgroud)

boo!(Option<i32>); 导致错误:

macro_rules! boo {
    ($T:ident) => {
        let x: $T;
    };
}

fn main() {
    boo!(i32);         // WORKS
    boo!(Option<i32>); // PROBLEM
}
Run Code Online (Sandbox Code Playgroud)

我可以解决它:

type Opti32 = Option<i32>;
boo!(Opti32);
Run Code Online (Sandbox Code Playgroud)

但是为宏的每次使用添加别名太无聊了。是否可以使用像这样的宏boo!(Option<i32>);并将困难隐藏在里面macro_rules

rust

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

OptionalInt作为输入参数

我读了为什么Java 8的Optional不能用在参数中.但是Optional(Int|Long|Double),有什么理由反对使用它们作为输入参数?

正如我所理解的那样,它们不能是空的,而是null(Optional<X>输入参数中的主要参数参数),但可能还有其他的珊瑚礁?我应该使用OptionalIntInteger使用null而不是null重视?

java optional java-8

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

为什么在结构分解后会有一个挂断电话?

我包装了C API。为了简化这个问题,我NonNull::dangling改用了。

use std::ptr::NonNull;

struct Foo(NonNull<i32>);

impl Drop for Foo {
    fn drop(&mut self) {
        println!("Foo::drop: {:?}", self.0);
    }
}

struct Moo(NonNull<i32>);
//impl Drop for Moo exists, but not important for question

fn f1() -> Result<Foo, String> {
    Ok(Foo(unsafe { NonNull::dangling() }))
}

fn f2() -> Result<Moo, String> {
    f1().map(|Foo(x)| Moo(x))//1
}

fn main() {
    f2();
}
Run Code Online (Sandbox Code Playgroud)

在第(1)点,我解包/分解Foo。我希望在那之后Foo::drop不应该调用它,但是出于某种原因Foo::drop会打印出来。

销毁(let Struct1 { field1, field2, .. } = struct1;)应该阻止调用,这是我错了Struct1::drop吗?

destructuring rust

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

serde:加速自定义枚举反序列化

我的程序解析了足够大的 json 文档(30MB),在 CPU 速度较慢的机器上需要 70 毫秒,我想加快这个过程,我发现 27% 的解析发生在我的foo_document_type_deserialize.有没有办法在String这里跳过分配:let s = String::deserialize(deserializer)?;

我完全确定表示枚举值的字符串不包含特殊的 json 字符,例如\b \f \n \r \t \" \\,因此使用未转义的字符串应该是安全的。

use serde::{Deserialize, Deserializer};

#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct FooDocument {
    // other fields...
    #[serde(rename = "type")]
    #[serde(deserialize_with = "foo_document_type_deserialize")]
    doc_type: FooDocumentType,
}

fn foo_document_type_deserialize<'de, D>(deserializer: D) -> Result<FooDocumentType, D::Error>
where
    D: Deserializer<'de>,
{
    use self::FooDocumentType::*;
    let s = String::deserialize(deserializer)?;
    match s.as_str() {
        "tir lim bom bom" => Ok(Var1), …
Run Code Online (Sandbox Code Playgroud)

rust serde

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

如何以独立于平台的方式使用leading_zeros/trailing_zeros?

我想在 a 的二进制表示中找到第一个非零位 u32leading_zeros/trailing_zeros看起来像我想要的:

let x: u32 = 0b01000;
println!("{}", x.trailing_zeros());
Run Code Online (Sandbox Code Playgroud)

这会按预期和文档中的描述打印3。在大端机器上会发生什么,是3还是其他数字?

文档说

返回二进制表示中尾随零的数量

它与机器二进制表示(因此结果trailing_zeros取决于体系结构)或基数为 2 的数字系统(因此结果始终为3)有关?

rust

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

标签 统计

rust ×7

c++ ×2

c++11 ×2

boost ×1

destructuring ×1

enums ×1

java ×1

java-8 ×1

optional ×1

reference ×1

serde ×1

slice ×1