我正在使用 Tokio,我想接收来自两个不同mpsc队列的请求。select!似乎是要走的路,但我不确定futures::select!和之间有什么区别tokio::select!。在哪种情况下,您应该使用一种而不是另一种?
我当前的代码如下所示:
pub trait A {}
pub trait HasA {
type A: A;
fn gimme_a() -> Self::A;
}
pub trait RichA: A {}
pub trait RichHasA: HasA {
type A: RichA;
fn gimme_a() -> Self::A;
// ... more things go here ...
}
pub fn main() {}
Run Code Online (Sandbox Code Playgroud)
我的目标是能够RichHasA用作HasA.上面的代码无法编译:
error[E0221]: ambiguous associated type `A` in bounds of `Self`
--> src/main.rs:10:21
|
3 | type A: A;
| ---------- ambiguous `A` from `HasA`
...
9 | type A: RichA; …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用可克隆迭代器对象定义一个结构。到目前为止,我已经达到:
pub struct UseClonableIterator2<'a,T:'a> {
it: &'a (Iterator<Item=T> + Clone)
}
Run Code Online (Sandbox Code Playgroud)
它无法编译,因为Clone不是“内置特征”:
x.rs:2:33: 2:38 error: only the builtin traits can be used as closure or object bounds [E0225]
x.rs:2 it: &'a (Iterator<Item=T> + Clone)
^~~~~
x.rs:2:33: 2:38 help: run `rustc --explain E0225` to see a detailed explanation
Run Code Online (Sandbox Code Playgroud)
一种选择可能是为迭代器添加另一个类型参数,但这会使定义复杂化,我宁愿避免它。
我一直在玩概念.这是一个最小的例子,我试图创建一个基于方法签名的概念:
template<typename T>
concept bool myConcept() {
return requires(T a, int i) {
{ a.foo() } -> int;
{ a.bar(i) } -> int;
};
}
struct Object {
int foo() {return 0;}
int bar(int) {return 0;}
};
static_assert(myConcept<Object>(), "Object does not adhere to myConcept");
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,写作{ a.bar(int) } -> int没有用,所以我求助于在requires表达式中添加一个额外的参数.这看起来有点奇怪,我想知道是否有办法做同样的事情.另一件有用的事情是使用类似的东西{ a.bar((int)0) } -> int,但我觉得这更糟糕.
查看: https: //github.com/NixOS/nixpkgs/blob/master/pkgs/development/libraries/pybind11/default.nix,在我看来,我应该能够避免运行测试(即 set -DPYBIND11_TEST=OFF)像下面这样:
pybind11 = pkgs.pybind11.overrideAttrs (oldAttrs: rec {
doCheck = false;
});
Run Code Online (Sandbox Code Playgroud)
然而,这是行不通的。
我通过直接修改cmakeFlags解决了我的问题:
pybind11 = pkgs.pybind11.overrideAttrs (oldAttrs: rec {
cmakeFlags = [
"-DPYTHON_EXECUTABLE=${pkgs.python.interpreter}"
"-DPYBIND11_TEST=OFF"
];
});
Run Code Online (Sandbox Code Playgroud)
但我想知道为什么前一种方法不起作用。
我正在尝试使用特征和相关类型在Rust上实现一些东西.我不确定如何用文字形成我的问题,所以我将添加一个代码片段,希望能说明我正在尝试做什么.
pub trait Person {}
pub trait Directory<P: Person> {
type Per = P;
fn get_person(&self) -> Self::Per;
}
pub trait Catalog {
type Per : Person;
type Dir : Directory<Self::Per>;
fn get_directory(&self) -> Self::Dir;
}
fn do_something<C>(catalog: C) where C: Catalog {
let directory : C::Dir = catalog.get_directory();
// let person : C::Per = directory.get_person();
// The code above fails with:
// error: mismatched types:
// expected `<C as Catalog>::Per`,
// found `<<C as Catalog>::Dir as Directory<<C as Catalog>::Per>>::Per` …Run Code Online (Sandbox Code Playgroud) 是否可以打印回溯记录(假设已启用RUST_BACKTRACE)而不会出现恐慌?似乎唯一的方法是通过调用panic!。如果没有,那是有原因的吗?
我想知道为什么矢量模板执行两个分配,只有一个似乎是必要的.
例如:
#include <vector>
#include <iostream>
class A {
public:
A(const A &a) {
std::cout << "Calling copy constructor " << this << " " << &a << "\n";
}
A() {
std::cout << "Calling default constructor " << this << "\n";
}
~A() {
std::cout << "Calling destructor " << this << "\n";
}
};
int main(int argc, char **argv)
{
std::vector <A> Avec;
std::cout << "resize start\n";
Avec.resize(1);
std::cout << "resize end\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
resize start …
以下代码有效吗?
struct foo {
int a;
int b[];
};
struct bar {
int c;
struct foo d;
};
struct bar *x = malloc(sizeof(struct bar) + sizeof(int [128]));
Run Code Online (Sandbox Code Playgroud)
对我来说似乎没问题,但我有点怀疑,因为如果我这样做,编译器不会抱怨:
struct bar {
struct foo d;
int c;
};
Run Code Online (Sandbox Code Playgroud) 这是一个例子:
use std::rc::Rc;
#[derive(PartialEq, Eq)]
struct MyId;
pub fn main() {
let rc_a_0 = Rc::new(MyId);
let rc_a_1 = rc_a_0.clone();
let rc_b_0 = Rc::new(MyId);
let rc_b_1 = rc_b_0.clone();
println!("rc_a_0 == rc_a_1: {:?}", rc_a_0 == rc_a_1);
println!("rc_a_0 == rc_b_0: {:?}", rc_a_0 == rc_b_0);
}
Run Code Online (Sandbox Code Playgroud)
两者都println!在印刷之上true.有没有办法区分rc_a_*和rc_b_*指针?
这是我正在尝试做的最小版本:
template<typename D>
struct Base {
void common() {
// ... do something ...
static_cast<D *>(this)->impl();
// ... do something ...
}
void common_with_arg(typename D::Arg arg) {
// ... do something ...
static_cast<D *>(this)->impl_with_arg(arg);
// ... do something more ...
}
};
struct Derived : Base<Derived> {
void impl() { }
using Arg = int;
void impl_with_arg(Arg arg) { }
};
Run Code Online (Sandbox Code Playgroud)
Base::common()并且Derived::impl()工作正常(如预期的那样).
Base::common_with_arg()并且Derived::impl_with_arg(),但是,没有.
以gcc为例,我收到以下错误:
1.cc: In instantiation of ‘struct Base<Derived>’:
1.cc:18:18: required from here …Run Code Online (Sandbox Code Playgroud) 考虑到这两个结构:
struct point {
int x,y;
};
struct pinfo {
struct point p;
unsigned long flags;
};
Run Code Online (Sandbox Code Playgroud)
还有一个改变观点的功能:
void p_map(struct point &p);
Run Code Online (Sandbox Code Playgroud)
是否可以使用boost(例如boost :: bind或boost :: lambda)创建一个等效的函数:
void pi_map(struct pinfo &pi) { p_map(pi.p); }
Run Code Online (Sandbox Code Playgroud)
-edit:更新以获取更多信息:
这个函数的初衷是在for_each中使用它.例如,给定此功能:
void p_map(struct point &p)
{
p.x += 1;
p.y += 1;
}
Run Code Online (Sandbox Code Playgroud)
我可以写:
void foreach(std::vector<struct pinfo> &pi_vec)
{
for_each(pi_vec.begin(), pi_vec.end(), pi_map);
}
Run Code Online (Sandbox Code Playgroud)
正如在答案中建议的那样,可以使用boost :: lambda绑定成员变量,并创建替代的for_each版本:
void foreach2(std::vector<struct pinfo> &pi_vec)
{
boost::function<void (pinfo&)> pi_map2 = bind(&p_map, bind(&pinfo::p, _1));
for_each(pi_vec.begin(), pi_vec.end(), pi_map2);
}
Run Code Online (Sandbox Code Playgroud)
我对这种方法的问题是,gcc(v.4.3.2)没有内联foreach2版本的pi_map和p_map函数.
为foreach1函数生成的x86代码是:
0000000000400dd0 …Run Code Online (Sandbox Code Playgroud) rust ×6
c++ ×4
asynchronous ×1
backtrace ×1
boost ×1
c ×1
c++-concepts ×1
crtp ×1
gcc ×1
identity ×1
nix ×1
performance ×1
rust-tokio ×1
stl ×1
traits ×1