小编Fil*_*ues的帖子

创建一个大小为 0 的数组会消耗价值,忘记它

我偶然发现了这个问题,在阅读了 ramslök 对已接受答案的评论后,我尝试了一个不是Copy.

令我惊讶的是它编译成功,但它的析构函数从未运行,有效地忘记了值,就好像std::mem::forget被调用一样。这是一个代码示例(Playground):

#[derive(PartialEq, Debug)]
struct A;

impl Drop for A {
    fn drop(&mut self) {
        println!("Dropping A");
    }
}

fn main() {
    let vec: Vec<A> = vec![];
    let a = A;
    assert_eq!(vec, [a; 0]);
}
Run Code Online (Sandbox Code Playgroud)

如果我们尝试在a之后使用assert_eq,它会抱怨该值已移动到数组中。

通过 已经可以忘记值std::mem::forget,并且它不会导致 UB,但仍然感觉很奇怪,如果没有编译器魔法是可能的。

我的问题是:这是一个错误,还是 Rust 的预期功能?

rust

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

比较对象可以作为const调用

当我尝试运行以下代码时,clang(6.0)和g ++(8)与-std = c ++ 17都会给我一个static_assert错误:

#include <set>
struct A {};

struct ProcessComparator { inline bool operator()(const A&, const A&) { return true; } };

int main(void)
{
    std::set<A, ProcessComparator> A_Set;

    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

g ++ 8

/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_tree.h:457:7:错误:由于需求'is_invocable_v',static_assert失败"比较对象必须作为const调用"

铿锵6.0

/usr/include/c++/8/bits/stl_tree.h:457:21:错误:静态断言失败:比较对象必须作为const调用

将const作为operator()签名的一部分来修复此问题:

#include <set>

struct A {};

/* Add const as part of the operator's signature */
struct ProcessComparator { inline bool operator()(const A&, const A&) const { return true; } };

int main(void)
{
    std::set<A, ProcessComparator> A_Set;

    return EXIT_SUCCESS;
} …
Run Code Online (Sandbox Code Playgroud)

c++ stl c++17

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

输出“i8”时,从内联汇编中删除多余的“andi ..., 0xff”指令

我有以下使用内联汇编的函数,目标mipsel-unknown-linux-gnu

#![feature(asm)]

#[no_mangle]
pub unsafe extern "C" fn f(ptr: u32) {
    let value: i8;
    asm!(
        "lb $v0, ($a0)",
        in("$4") ptr,
        out("$2") value,
    );
    asm!(
        "sb $v0, ($a0)",
        in("$4") ptr,
        in("$2") value,
    );
}
Run Code Online (Sandbox Code Playgroud)

我预计这会编译成以下内容:

lb $v0, ($a0)
sb $v0, ($a0)
jr $ra
nop
Run Code Online (Sandbox Code Playgroud)

注意:在此示例中,编译器可能会在跳转后将存储指令重新排序以使用延迟槽,但在我的实际用例中,我通过块返回asm,因此不必担心。鉴于此,我完全预料到了上面的装配。

相反,我得到的是:

00000000 <f>:
   0:   80820000        lb      v0,0(a0)
   4:   304200ff        andi    v0,v0,0xff
   8:   a0820000        sb      v0,0(a0)
   c:   03e00008        jr      ra
  10:   00000000        nop
Run Code Online (Sandbox Code Playgroud)

编译器似乎不相信我的输出是 ani8andi $v0, 0xff在那里插入了一条指令。

我需要准确地生成上面指定的程序集,因此我想删除该andi …

mips inline-assembly rust

7
推荐指数
0
解决办法
189
查看次数

调整大小后保持对向量元素的引用有效

如果我们引用向量元素,然后调整向量的大小,则引用不再有效,迭代器也会发生同样的情况:

std::vector<int> vec{0, 1, 2, 3, 4, 5};
int& ref = vec[0];
auto itr = vec.begin();

cout <<  ref << " " << *itr << endl;

vec[0] = 7;

cout <<  ref << " " << *itr << endl;

vec.resize(100);
vec[0] = 3;

cout <<  ref << " " << *itr << endl;
Run Code Online (Sandbox Code Playgroud)

打印出:

0 0
7 7
0 0 // We expected a 3 here
Run Code Online (Sandbox Code Playgroud)

我知道只保留对向量本身的引用并调用 vec[0] 会更实用,但只是为了提问,是否可以保留一个始终为 vec[0] 的对象,即使物体被移动了?

我尝试编写一个小帮助器类来帮助解决此问题,但我不确定这是否是最好的方法,或者它是否会失败?

template<typename T>
struct HelperClass
{
    std::vector<T>& vec;
    size_t …
Run Code Online (Sandbox Code Playgroud)

c++ reference vector

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

C++模板<Operator>

我正在构建一个BigInt类,当重载运算符时,| 和^,都将具有相似的函数语法,我想知道是否可以模拟运算符本身:

template<operator K> 
BigInt operator K( const BigInt& a, const BigInt& b )
{
 BigInt Result = 0;
 uint64_t Max = max(a.GetSize() , b.GetSize()) /* max(a,b) is defined outside */
 for (uint64_t n=0; n < Max; n++)
 {
  Result[n] = a[n] K b[N];
 }
 return Result;
}
Run Code Online (Sandbox Code Playgroud)

其中A [n]返回带有第n个数字(二进制​​)的bool,并将其应用于运算符&,| 和^,这样我就不会写出3个运算符重载,它们对于2个字母的例外都是相同的.

我知道这种语法不起作用,但我问是否有任何方法可以做你可能期望这种语法做的事情:用&替换K,| 或^,只有你在代码中写(a和b)时的那些.

如果它有帮助,这是我对类的定义:

class BigInt
{
private:
    vector<bool> num;

public:
    /* Constructors */
    BigInt();
    template<class T> BigInt(T);

    /* Class Methods */
    void RLZ(); /* Remove Leading Zeroes */
    uint64_t …
Run Code Online (Sandbox Code Playgroud)

c++ templates operator-overloading

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