c语言move函数,C语言中C ++标准11实现的std :: move函数(An std::move function of C++ standard 11 implementation in C)...

C语言中C ++标准11实现的std :: move函数(An std::move function of C++ standard 11 implementation in C)

我们都知道在C ++标准11中实现的std :: move函数的强大功能,它将特定范围内的元素移动到新范围。

我想知道我是否可以在纯C代码中开发这样的功能。 我的代码是用C语言编写的,我希望有类似于C ++的std :: move函数,我可以在不使用临时缓冲区的情况下将整数元素的范围移动到新的范围内。

We are all aware of the powerful functionality of the std::move function that is implemented in the C++ standard 11, where it moves the elements in a specific range into a new range.

I would like to know if I can develop such a functionality in pure C code. My code is written in C and I want to have something similar to the std::move function of C++, where I can move the range of integer elements into a new range without using a temporary buffer.

原文:https://stackoverflow.com/questions/33820875

更新时间:2019-12-03 23:58

最满意答案

关于你的文字:

...将特定范围内的元素移动到新范围内。

和:

...我可以在不使用临时缓冲区的情况下将一系列整数元素移动到新范围内。

我认为你所追求的是memmove 。 它就像memcpy但处理重叠区域没有问题。

例如,以下代码将(从3开始)(从零开始)移动(复制,实际)元素到范围2到5:

#include

#include

int main (int argc, char *argv[]) {

int xyzzy[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

memmove (&(xyzzy[2]), &(xyzzy[3]), sizeof(*xyzzy) * 4);

printf ("{ %d", xyzzy[0]);

for (int i = 1; i < sizeof(xyzzy) / sizeof(*xyzzy); i++)

printf (", %d", xyzzy[i]);

printf (" }\n");

return 0;

}

基本上:

{0 1 2 3 4 5 6 7 8 9}

| | | |

/ / / /

| | | |

V V V V

{0 1 3 4 5 6 6 7 8 9}

Regarding your text:

... moves the elements in a specific range into a new range.

and:

... where I can move a range of integer elements into a new range without using a temporary buffer.

I think the thing you're after is memmove. It's like memcpy but handles overlapping regions without issue.

For example, the following code moves (copies, really) elements from the range 3 through 6 (zero-based) to the range 2 through 5:

#include

#include

int main (int argc, char *argv[]) {

int xyzzy[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

memmove (&(xyzzy[2]), &(xyzzy[3]), sizeof(*xyzzy) * 4);

printf ("{ %d", xyzzy[0]);

for (int i = 1; i < sizeof(xyzzy) / sizeof(*xyzzy); i++)

printf (", %d", xyzzy[i]);

printf (" }\n");

return 0;

}

which basically does:

{0 1 2 3 4 5 6 7 8 9}

| | | |

/ / / /

| | | |

V V V V

{0 1 3 4 5 6 6 7 8 9}

2015-11-20

相关问答

这里的两个关键陈述是: 就好像在一个由thread对象表示的执行的新线程中一样 thread对象以共享状态存储并影响引用该状态的任何异步返回对象的行为。 “如果”意味着它必须像为它创建一个std::thread对象一样运行。 这意味着创建一个std::thread所有副作用也必须发生。 话虽如此,如果您将launch::async与launch::deferred结合起来,那么实现将决定是启动一个新线程还是将其推迟到现有线程。 所以只有launch::async才需要一个新的线程。 The two

...

反之。 对临时对象使用std::move毫无意义。 它们已经是R值,并且在传递给函数时将被推导为R值引用。 std::move的全部要点是将L值转换为R值引用,以便它们可以从中移出。 所以我认为窃取(移动)其元素数据是安全的,因为它们不会再被使用。 是的,这是正确的。 On the contrary. Using std::move on temporary objects is pointless. They're already R-values, and will be deduced as

...

首先,我会解决的问题可能是一个误解: 每当你看到代码中的T&& t (和T是一个实际的类型,而不是模板类型),请记住t的值类别是一个左值(引用),而不是rvalue(临时的)。 这很混乱 T&&只是意味着t是由一个rvalue 1的对象构成的,但是t 本身就是一个左值,而不是一个右值。 如果它有一个名称(在这种情况下, t ),那么它是一个左值,并且不会自动移动,但是如果没有名称( 3+4的结果),则它是一个右值,并将自动移入其结果if它可以。 类型 (在这种情况下, T&& )几乎与变量的值类别

...

那么我把一个测试程序扔在一起,每个方法都运行100,000次,一半是存在的文件,一半是没有文件的。 #include

#include

#include

inline bool exists_test0 (const std::string& name) {

ifstream f(name.c_str());

return f.good();

}

inline bool exists_test1 (const s

...

关于你的文字: ...将特定范围内的元素移动到新范围内。 和: ...我可以在不使用临时缓冲区的情况下将一系列整数元素移动到新范围内。 我认为你所追求的是memmove 。 它就像memcpy但处理重叠区域没有问题。 例如,以下代码将(从3开始)(从零开始)移动(复制,实际)元素到范围2到5: #include

#include

int main (int argc, char *argv[]) {

int xyzzy[] = {0, 1, 2,

...

是的,这将有效。 重要的是你不应该将类型安全与兼容性混淆。 你没有将std::function 作为 boost::function传递。 你告诉编译器将 std::function 包装 成 boost::function 。 这可能效率不高 - 因为每个都会在调用时添加另一层间接。 但它会奏效。 对于lambdas来说也是如此:lambdas没有什么神奇之处,它只是函数对象的语法糖。 Yes this will work. The important thing is that you sho

...

根据C ++ 11标准, std::function有一个无约束的构造函数模板,它接受任何参数类型: template function(F f);

当你说qworker{std::move(rhs.qworker)}这首先尝试使用std::initializer_list<:function>>来调用构造std::initializer_list<:function>> 。 由于上面显示的是无约束的构造函数模板,可以从任何类型构造s

...

你只需要使lambda取string (按值)或string const & (通过常量引用)或string && (rvalue引用)来支持移动。 在这种情况下,因为您正在修改s ,并且您不能使用string const & 。 thread t([](string && s){cout << s << endl; s = "Ni hao!";}, move(s));

它失败了,因为你无法将rvalue引用( string && )传递给带有左值引用的函数/ lambda( string &

...

不,这不安全。 参数的eval顺序未在标准中指定。 所以你的代码可以运行为: std::move(p) 。 调用std::unique_ptr move构造函数。 p.get() (因为2.,这将是nullptr 。)并传递此参数。 打电话给foo 。 你必须这样做: int *raw = p.get();

foo(raw, std::move(p));

请注意,您的代码可以很好地工作,因为一些编译器可以将您的代码编译为3 - > 1 - > 2 - > 4.但是,这并不意味着代码是安

...

几种方式: std :: move调用赋值运算符,而memmove则不调用赋值运算符。 因此,memmove不适用于非POD类型。 std :: move将适用于任何C ++容器类型,而memmove只适用于在连续内存位置线性存储元素的那些(例如使用数组和std :: vector)。 std :: move不适合与左侧源范围重叠的目标范围(使用move_backwards),而memmove适用于所有重叠范围。 在将POD类型复制到右重叠范围的情况下,memmove和std :: move可能具

...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值