我正在为特定类实现比较运算符重载foo:
class foo{
public:
foo() {};
};
bool operator==(foo&& lhs, foo&& rhs){
// ...
return true;
}
bool operator!=(foo&& lhs, foo&& rhs){
return operator==(lhs,rhs);
}
Run Code Online (Sandbox Code Playgroud)
但是,在调用!=运算符时,出现以下编译错误:
tester.cpp: In function ‘bool operator!=(foo&&, foo&&)’:
tester.cpp:37:27: error: no matching function for call to ‘operator==(foo&, foo&)’
return operator==(lhs,rhs);
^
tester.cpp:33:6: note: candidate: ‘bool operator==(foo&&, foo&&)’ <near match>
bool operator==(foo&& lhs, foo&& rhs){
^~~~~~~~
tester.cpp:33:6: note: conversion of argument 2 would be ill-formed:
tester.cpp:37:24: error: cannot bind rvalue reference of type …Run Code Online (Sandbox Code Playgroud) 这是我上一个问题的后续问题。
考虑以下玩具代码:
#include <iostream>
using namespace std;
class X
{
public:
X() { }
X(X&& x)
{
cout << "move ctor\n";
}
/*X(X& x)
{
cout << "copy ctor\n";
}*/
};
X f()
{
static X x;
X&& y = std::move(x);
X& z = x;
return y;
}
int main()
{
f();
}
Run Code Online (Sandbox Code Playgroud)
根据我对上一个问题(即class.copy.elision#3use of deleted function 'constexpr X::X(const X&)' )的理解,我认为这会导致上述代码中的错误( )返回y到f().
问题是,我在 PC 上的 Visual Studio 中运行代码,它编译并打印move ctor. 所以我 …
我很好奇,使用std::move将左值整数转换为右值与0向该整数添加 a 之间有什么实际区别吗?或任何其他中性算术运算(乘以1、减去0等)。
添加0:
int f(int&& i){
i++;
return i;
}
int main(){
int x = 43;
f(x+0);
}
Run Code Online (Sandbox Code Playgroud)
使用std::move:
#include <iostream>
int f(int&& i){
i++;
return i;
}
int main(){
int x = 43;
f(std::move(x));
}
Run Code Online (Sandbox Code Playgroud)
我知道我们不能对所有类型执行这种中立的操作,但我的问题特别是关于整数而不是其他类型。
#include <range/v3/all.hpp>
#include <vector>
#include <string>
#include <deque>
using namespace std::literals;
int main()
{
auto src = std::vector{"123"s, "456"s, "789"s};
auto movable_rng = ranges::subrange(
std::make_move_iterator(src.begin()),
std::make_move_iterator(src.end()));
auto dst = ranges::to<std::deque<std::string>>(movable_rng);
for (auto e : src)
{
std::cout << e << std::endl;
}
for (auto e : dst)
{
std::cout << e << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
用 libc++ 用 clang 10 编译,输出为:
123
456
789
123
456
789
Run Code Online (Sandbox Code Playgroud)
正如我所料,结果应该是:
""
""
""
123
456
789
Run Code Online (Sandbox Code Playgroud)
为什么即使是迭代器,ranges-v3 也不移动元素 std::move_iterator?
========更新======
我的范围版本是: …
我有这个练习,其中我们使用模板类尝试右值和左值引用的各种组合,我收到两个断言错误;如果有人可以指导的话。
#include <assert.h>
typedef int& IntLRef;
typedef IntLRef& IntLLRef;
typedef IntLRef&& IntLRRef;
typedef int&& IntRRef;
typedef IntRRef& IntRLRef;
typedef IntRRef&& IntRRRef;
template<typename T, typename U>
struct IsSameType
{
static const bool value = false;
};
template<typename T>
struct IsSameType <T, T>
{
static const bool value = true;
};
static_assert(IsSameType<IntLRef, IntLLRef>::value, "LRef DIF LLRef"); static_assert(IsSameType<IntLRef, IntLRRef>::value, "LRef DIF LRRef"); static_assert(IsSameType<IntLLRef, IntLRRef>::value, "LLRef DIF LRRef");
static_assert(IsSameType<IntRRef, IntRLRef>::value, "RRef DIF RLRef"); static_assert(IsSameType<IntRRef, IntRRRef>::value, "RRef DIF RRRef"); static_assert(IsSameType<IntRLRef, IntRRRef>::value, "RLRef DIF RRRef");
int …Run Code Online (Sandbox Code Playgroud) 我用 C++20 编写了一个无锁且线程安全的环形队列,到目前为止它可以工作。唯一不完美的是它必须有两个enque()方法,一个接受对左值的 const 引用作为参数,另一个接受对右值的引用,以便将右值移入队列而不是再次构造。
之前版本的代码如下,只是一个骨架,进行简化:
\ntemplate <typename T>\nclass RingQue_t {\npublic:\n explicit RingQue_t( size_t capacity );\n ~RingQue_t();\n bool deque( T& dest_ ) { return true; };\n\n // If we offer a const ref, the compiler will select this one\n bool enque( const T& src_ ) {\n // a lot of same codes goes here for a same logic...\n\n new( _buff + _tail ) T( src_ );\n };\n\n // If we offer a rvalue ref, the compiler …Run Code Online (Sandbox Code Playgroud) c++ copy-constructor rvalue-reference move-constructor perfect-forwarding
我正在编写一个对象分配器,我想通过以下方式调用它:
T result = factoryObject.construct(argA, argB, argC);
Run Code Online (Sandbox Code Playgroud)
我目前有这个设计,它有效......
class Factory {
void* memPool_;
template <typename Tret, typename... Args>
Tret construct(Args&&... args) {
Tret::methodA(std::forward<Args&&>(args));
Tret::Tret(memPool_, std::forward<Args&&>(args);
}
}
Run Code Online (Sandbox Code Playgroud)
...只要我用以下方式调用它:
T result = factoryObject.construct<T>(argA, argB, argC);
Run Code Online (Sandbox Code Playgroud)
我希望能够在不明确指定的情况下做到这一点T。T可能会变得非常复杂,我需要在初始化列表中使用这个工厂内联。我还需要在构造函数初始化列表中使用它,所以我无法调用auto result = factory.construct<T>()(我只需要它根据它正在构造的内容推断返回类型)。
我尝试使用operator()技巧推断类型(根据/sf/answers/182910731/):
public:
template <class T>
operator T() { return T(); }
};
class GC {
public:
static Allocator Allocate() { return Allocator(); }
};
int main() {
int p = GC::Allocate();
}
Run Code Online (Sandbox Code Playgroud)
...但这不允许我传递参数(因为 operator() …
我有一个返回右值引用的函数.
auto function() -> int&& {
int x{10};
std::cout << x << std::endl; // to check the value of x
return std::move(x);
}
Run Code Online (Sandbox Code Playgroud)
现在,当我使用以下代码时:
std::cout << function() << std::endl;
std::vector<int> v;
v.push_back(function());
std::cout << v[0] << std::endl;
Run Code Online (Sandbox Code Playgroud)
这导致以下输出
10
0
Run Code Online (Sandbox Code Playgroud)
看起来即使function()返回一个rvalue-reference,vector也会推回一个默认的构造int.
有趣的是,如果我有这样的代码:
auto x = function();
v.push_back(std::move(x));
Run Code Online (Sandbox Code Playgroud)
这非常有效.
看来如果我只是从函数返回一个局部变量,那么RVO无论如何都会做一个复制省略.但是因为我正在做一个明确的std :: move()我正在绊倒RVO导致返回一个临时变量.
现在,在v.push_back(function())中我调用了vector :: push_back(T &&)函数,导致引用对temp变量的引用.在这种情况下,它总是倾向于0而不是垃圾(我猜这是因为优化打开).
但是,如果我尝试在局部变量中捕获function()的返回值,它可能会起作用,大概是因为在返回值的过程中创建的临时变量的值被复制到此局部变量.对于未定义的行为,这看起来并不幸运.