有了const,如评论所示,msvc 11和g ++ 4.7.0拒绝编译:
#include <memory> // std::unique_ptr
#include <utility> // std::move
using namespace std;
struct CommandLineArgs
{
typedef unique_ptr<
wchar_t const* const [],
void(*)( wchar_t const* const* )
> PointerArray;
//PointerArray const args; // Oops
PointerArray args;
int const count;
static wchar_t const* const* parsed(
wchar_t const commandLine[],
int& count
)
{
return 0;
}
static void deallocate( wchar_t const* const* const p )
{
}
CommandLineArgs(
wchar_t const commandLine[] = L"",
int _ = 0
) …Run Code Online (Sandbox Code Playgroud) 我写了一个程序如下:
#include <iostream>
using namespace std;
class A {
public:
A() {
}
A(A &a) {
id = a.id;
cout << "copy constructor" << endl;
}
A& operator=(A &other) {
id = other.id;
cout << "copy assignment" << endl;
return *this;
}
A(A &&other) {
id = other.id;
cout << "move constructor" << endl;
}
A& operator=(A &&other) {
id = other.id;
cout << "move assignment" << endl;
return *this;
}
public:
int id = 10;
};
A foo() { …Run Code Online (Sandbox Code Playgroud) 我正在测试一个移动构造函数并执行以下操作:
#include <iostream>
#include <string>
using namespace std;
class X{
public:
int* p;
int size;
X(){}
X(int n) : size(n){
p = new int[n];
for(int i = 0; i < n; i++)
p[i] = i;
cout << "Constructor\n";
}
~X(){
delete[] p;
}
X(const X& r){
cout << "Copy\n";
}
X(X&& r){
p = r.p;
size = r.size;
r.p = NULL;
r.size = 0;
cout << "Move\n";
}
};
int main() {
X a(10); //constructor
X b(a); // copy
X …Run Code Online (Sandbox Code Playgroud) 考虑下面运行C++ 11的代码.如果我理解正确的移动语义,则不应该调用复制构造函数.但它是.有人可以解释原因吗?
template<class D>
struct traced
{
public:
traced() = default;
traced(traced const&) { std::cout << typeid(D).name() << " copy ctor\n"; }
protected:
~traced() = default;
};
class A : public traced<A>{
public:
A(int x) : x_(x) {}
private:
int x_;
};
int main() {
// I thought the following two are equivalent. Apparently not.
aList.push_back(A(6)); // Prints out ".. copy ctor" ..
aList.emplace_back(6); // Does not print out " ... copy ctor"
}
Run Code Online (Sandbox Code Playgroud) 我正在努力深入了解如何编写副本并移动构造函数和赋值运算符.
在Bjarne Stroustrup的"The C++ Programming Language - 2013"中,我看到了以下移动构造函数和移动赋值的示例:
template<class T, class A>
vector_base<T,A>::vector_base(vector_base&& a)
: alloc{a.alloc},
elem{a.elem},
space{a.space},
last{a.space}
{
a.elem = a.space = a.last = nullptr; // no longer owns any memory
}
template<class T, class A>
vector_base<T,A>::& vector_base<T,A>::operator=(vector_base&& a)
{
swap(?this,a);
return *this;
}
Run Code Online (Sandbox Code Playgroud)
(旁注:书中似乎有一个拼写错误:::&应该是正确的&,对吧?)
我怀疑它应该导致无休止的递归,因为std::swap()调用移动赋值运算符:
template<typename T>
void swap(T& lhs, T& rhs)
{
auto temp(lhs);
lhs = std::move(rhs);
rhs = std::move(temp);
}
Run Code Online (Sandbox Code Playgroud)
我查了一下,这是一个非常简单的程序:
#include <iostream>
using namespace std;
class …Run Code Online (Sandbox Code Playgroud) 我说有一个标准容器的类:
class Library{
std::vector<Book> books;
public:
void putOnFire(){
books.clear();
}
};
Run Code Online (Sandbox Code Playgroud)
清除容器的常用方法是"清除",但是大多数代码不符合"STL",因此许多容器(第三方)可能没有"清除"方法.但是,如果他们有移动语义我可以使用std :: move对吗?
void putOnFire(){
auto p = std::move(books); //books cleared when p out of scope
}
Run Code Online (Sandbox Code Playgroud)
这是编写大多数通用的可能代码,这些代码也适用于不具有"clear"方法的STL容器.
我有这样的代码:
class Pair{
public:
Pair(Pair && other){};
Pair(Pair & other){};
};
class IROList{
public:
virtual const Pair get(const char *key) const = 0;
inline const Pair operator[](const char *key) const{
return this->get(key);
// error: binding ‘const Pair’ to reference of type ‘Pair&&’ discards qualifiers
}
};
Run Code Online (Sandbox Code Playgroud)
在编译时,它产生
error: binding ‘const Pair’ to reference of type ‘Pair&&’ discards qualifiers
Run Code Online (Sandbox Code Playgroud)
如果我将移动构造函数更改为const,则错误消失.
Pair(const Pair && other){};
Run Code Online (Sandbox Code Playgroud)
但是,如果移动构造函数采用const,我无法真正移动数据.我应该复制它.
除了删除返回方法的const之外,是否有任何解决方法,例如
virtual Pair get(const char *key) const = 0;
inline Pair operator[](const char *key) const;
Run Code Online (Sandbox Code Playgroud) 我知道这可以用来执行完美的转发:
template <typename A>
void foo(A&&) { /* */ }
Run Code Online (Sandbox Code Playgroud)
这可以用于在某种类型上执行完美转发:
template <typename A, std::enable_if_t<std::is_same<std::decay_t<A>, int>::value, int> = 0>
void foo(A&&) { /* */ }
Run Code Online (Sandbox Code Playgroud)
但这些只是函数的模板,这意味着,这些函数会扩展为某些函数,然后将这些函数用于可能使用它的每个特殊情况.但是,这些扩展到:
void foo(A&) 和 void foo(A&&)
要么
void foo(A&) 和 void foo(A)
我一直认为,这将是第一个,但后来我注意到,在那种情况下,你将无法A const用作函数的参数,这当然有效.
然而,如果您使用正常的非常数左值,则第二个将是不明确的.它会打电话foo(A&)还是foo(A)?
c++ templates rvalue-reference move-semantics perfect-forwarding
我有一个由函数更改的numpy数组。调用函数后,我要继续使用数组的初始值(调用修改函数之前的值)
# Init of the array
array = np.array([1, 2, 3])
# Function that modifies array
func(array)
# Print the init value [1,2,3]
print(array)
Run Code Online (Sandbox Code Playgroud)
有没有一种方法可以按值传递数组,或者我有义务进行深拷贝?
我想与你分享一个我无法解决的小问题,这里是代码(仅供测试):
#include <windows.h>
#include <iostream>
#include <vector>
#include <string>
#include <utility>
#include <type_traits>
#include <sstream>
struct Procedure {
Procedure(HANDLE)
{ std::cout << "ctor w/connection: " << this << std::endl; }
~Procedure()
{ std::cout << "dtor: " << this << std::endl; }
Procedure(Procedure &&rhs) {
std::cout << "ctor w/move: " << this << std::endl;
this->m_Params = std::move(rhs.m_Params);
}
Procedure& operator= (Procedure &&rhs) {
std::cout << "operator= w/move: " << this << std::endl;
if (this != &rhs) this->m_Params = std::move(rhs.m_Params);
return *this; …Run Code Online (Sandbox Code Playgroud)