#include <set>
#include <string>
#include <cassert>
using namespace std::literals;
int main()
{
auto coll = std::set{ "hello"s };
auto s = "hello"s;
coll.insert(std::move(s));
assert("hello"s == s); // Always OK?
}
Run Code Online (Sandbox Code Playgroud)
C ++标准是否保证插入关联容器失败不会修改rvalue-reference参数?
c++ stl rvalue-reference language-lawyer pass-by-rvalue-reference
我有一个类'记住'对某个对象的引用(例如整数变量).我不能让它引用一个立即被破坏的值,我正在寻找一种方法来保护我班级的用户不会这样做.
rvalue-reference重载是防止临时传入的好方法吗?
struct HasRef {
int& a;
HasRef(int& a):a(a){}
void foo(){ a=1; }
};
int main(){
int x=5;
HasRef r1(x);
r1.foo(); // works like intended.
HasRef r2(x+4);
r2.foo(); // dereferences the temporary created by x+4
}
Run Code Online (Sandbox Code Playgroud)
私有rvalue超载会吗?
struct HasRef {
int& a;
HasRef( int& a ):a(a){}
void foo(){ a=1; }
private:
HasRef( int&& a );
};
... HasRef r2(x+1); // doesn't compile => problem solved?
Run Code Online (Sandbox Code Playgroud)
我有没有看到任何陷阱?
c++ pass-by-reference rvalue-reference pass-by-rvalue-reference
我想开发一个带有类型擦除的小型多态类,我想知道哪个版本的模板化构造函数更好,应该使用.
我们可以通过价值:
class A
{
...
template< typename T >
A( T t ) { /* create the underlying model via std::move */ }
...
};
Run Code Online (Sandbox Code Playgroud)
或者我们可以使用通用参考:
class A
{
...
template< typename T >
A( T &&t ) { /* create the underlying model via std::forward */ }
...
};
Run Code Online (Sandbox Code Playgroud)
(如果对于T不是类本身并且未复制类的情况,则必须启用通用引用).有任何想法吗?这两个版本看起来都和我一样.
c++ pass-by-value pass-by-rvalue-reference forwarding-reference
我有一个代码:
void f(int&& i) {
auto lambda = [](int&& j) { (void)j; }
lambda(i);
}
int main() {
f(5);
}
Run Code Online (Sandbox Code Playgroud)
Clang ++给出了一个错误: no known conversion from 'int' to 'int &&' for 1st argument
为什么在传递给i它int时改变它的类型lambda()?
如果我有课A和功能
A f(A &&a)
{
doSomething(a);
return a;
}
A g(A a)
{
doSomething(a);
return a;
}
Run Code Online (Sandbox Code Playgroud)
返回时,拷贝构造函数被调用a的f,但返回时移动的构造函数使用g.但是,根据我的理解,f只能传递一个可以安全移动的对象(临时或标记为可移动的对象,例如,使用std::move).有什么例子,当从返回时使用移动构造函数是不安全的f吗?为什么我们要求a有自动存储时间?
我在这里阅读了答案,但最顶层的答案只表明规范不应允许在传递a给函数体中的其他函数时移动; 它没有解释为什么在返回时移动是安全的g但不是安全的f.一旦我们到达return语句,我们就不再需要a了f.
所以我理解临时表可以在完整表达结束之前访问.然而,从f仍然返回时的行为似乎违背了根深蒂固的语义,即移动临时或xvalue是安全的.例如,如果您调用g(A()),临时将移动到参数中,g即使可能存在对某处临时存储的引用.如果我们g使用xvalue 调用,也会发生同样的情况.因为只有temporaries和xvalues绑定到rvalue引用,所以看起来我们a在返回时仍应该移动的语义是一致的f,因为我们知道a传递了临时或xvalue.
考虑这个例子:
#include <utility>
// runtime dominated by argument passing
template <class T>
void foo(T t) {}
int main() {
int i(0);
foo<int>(i); // fast -- int is scalar type
foo<int&>(i); // slow -- lvalue reference overhead
foo<int&&>(std::move(i)); // ???
}
Run Code Online (Sandbox Code Playgroud)
是foo<int&&>(i)快foo<int>(i),还是涉及指针开销foo<int&>(i)?
编辑:作为建议,跑步g++ -S给了我同样51管路组件文件foo<int>(i)和foo<int&>(i),但foo<int&&>(std::move(i))导致71行的汇编代码(它看起来像差异的来源std::move).
编辑:感谢那些推荐g++ -S不同优化级别的人 - 使用-O3(和制作foo noinline)我能够获得看起来像xaxxon解决方案的输出.
我无法理解此错误的实质,因此,如果标题更好,请原谅。此代码无法编译:
template <auto v>
struct value_as_type {
using type = decltype(v);
static constexpr type value {v};
constexpr operator type() const {
return v;
}
};
template <int First, int Last, typename Functor>
constexpr void static_for([[maybe_unused]] Functor&& f)
{
if constexpr (First < Last)
{
f(value_as_type<First>{});
static_for<First + 1, Last, Functor>(std::forward<Functor>(f));
}
}
template <class... FieldsSequence>
struct DbRecord
{
private:
static constexpr bool checkAssertions()
{
static_assert(sizeof...(FieldsSequence) > 0);
static_for<1, sizeof...(FieldsSequence)>([](auto&& index) {
constexpr int i = index;
static_assert(i > 0 && …Run Code Online (Sandbox Code Playgroud) c++ rvalue-reference constexpr pass-by-rvalue-reference c++17
假设我有这个功能:
void foo(Object& o) {
/* only query o, dont alter it*/
}
Run Code Online (Sandbox Code Playgroud)
是否可以仅使用已构造的对象调用此函数,并且如果我使用临时对象调用该函数,Visual Studio 会抛出编译错误?
struct Object {
/*Members*/
}
void foo(Object& o) {
/* only query o, dont alter it*/
}
int main() {
Object o = Object();
foo(o); // allow this
foo(Object()) // but disallow this
}
Run Code Online (Sandbox Code Playgroud) c++ function visual-studio move-semantics pass-by-rvalue-reference
关于“更简单的隐式移动”(P2266R1)提案,我不确定我是否正确理解了这个新的“符合移动条件”的东西。
如果不正确,请更正以下几点:
[直播]
std::forward 成为完美转发收到的右值参考的可选template<class T>
T&& seven(T&& x) { return std::forward<T&&>(x); }
Run Code Online (Sandbox Code Playgroud)
变成
template<class T>
T&& seven(T&& x) { return x; }
Run Code Online (Sandbox Code Playgroud)
std::move 对于本地创建的 rvalue ref 成为可选Widget&&
test_seven(Widget w) {
Widget&& rr = seven(std::move(w));
return std::move(rr);
}
Run Code Online (Sandbox Code Playgroud)
变成
Widget&&
test_seven(Widget w) {
Widget&& rr = seven(std::move(w));
return rr;
}
Run Code Online (Sandbox Code Playgroud)
std::moveoptionaly 变为parenthesis only为本地创建的事物返回一个右值引用。Widget&& h3(Widget t) {
return std::move(t);
}
Run Code Online (Sandbox Code Playgroud)
变成
Widget&& h3(Widget t) {
return (t);
}
Run Code Online (Sandbox Code Playgroud)
注意:(3) : clang …
c++ rvalue-reference move-semantics pass-by-rvalue-reference c++23
在我的代码中,我有一个函数,它从一段数据构造一个字符串然后返回它.此字符串不会在其他任何地方使用,因此接收方可以安全地使用移动分配或移动初始化.
std::string ReadString(...) {
...
return std::string(...)
}
Run Code Online (Sandbox Code Playgroud)
这基本上就是我所拥有的.在函数返回类型std :: string &&中是否有任何意义,因为返回的值是rvalue?
std::string&& ReadString(...) {
...
return std::string(...)
}
Run Code Online (Sandbox Code Playgroud)
我担心的是,当我们返回字符串时可能会有一个多余的副本,并且可以通过使返回类型为右值引用来缓解它.
我怀疑编译器也可以针对这些场景进行优化,但是,我不确定.
所以问题是 - 在这种情况下,返回类型是否为rvalue引用有什么意义?为什么?此外,如果没有,那么返回右值引用的函数有哪些可能的应用程序?
谢谢.