我是新手在C++ 11中移动语义,我不太清楚如何处理unique_ptr构造函数或函数中的参数.考虑这个引用自身的类:
#include <memory>
class Base
{
public:
typedef unique_ptr<Base> UPtr;
Base(){}
Base(Base::UPtr n):next(std::move(n)){}
virtual ~Base(){}
void setNext(Base::UPtr n)
{
next = std::move(n);
}
protected :
Base::UPtr next;
};
Run Code Online (Sandbox Code Playgroud)
这是我应该如何编写unique_ptr参数的函数?
我需要std::move在调用代码中使用吗?
Base::UPtr b1;
Base::UPtr b2(new Base());
b1->setNext(b2); //should I write b1->setNext(std::move(b2)); instead?
Run Code Online (Sandbox Code Playgroud) 我正在学习c ++ 11中的新功能并遇到了这个问题.我想通过在lambda中移动它作为for_each的参数来捕获unique_ptr.
建立:
std::array<int,4> arr = {1,3,5,6};
std::unique_ptr<int> p(new int); (*p) = 3;
Run Code Online (Sandbox Code Playgroud)
尝试1 - 不起作用,因为unique_ptr没有复制构造函数.c ++ 0x没有指定移动语法.
std::for_each(arr.begin(), arr.end(), [p](int& i) { i+=*p; });
Run Code Online (Sandbox Code Playgroud)
尝试2 - 使用bind将p的移动副本绑定到一个带有int&的函数:
std::for_each(arr.begin(), arr.end(),
std::bind([](const unique_ptr<int>& p, int& i){
i += (*p);
}, std::move(p))
);
Run Code Online (Sandbox Code Playgroud)
编译器抱怨说 'result' : symbol is neither a class template nor a function template.
这个练习的主要目的是了解如何在lambda中捕获可移动变量,该lambda被缓存以供以后使用.
我正在尝试使以下代码工作:
#include <cstdio>
#include <functional>
#include <string>
#include <memory>
using namespace std;
class Foo {
public:
Foo(): m_str("foo") { }
void f1(string s1, string s2, unique_ptr<Foo> p)
{
printf("1: %s %s %s\n", s1.c_str(), s2.c_str(), p->str());
}
void f2(string s1, string s2, Foo* p)
{
printf("2: %s %s %s\n", s1.c_str(), s2.c_str(), p->str());
}
const char* str() const { return m_str.c_str(); }
private:
string m_str;
};
int main()
{
string arg1 = "arg1";
string arg2 = "arg2";
Foo s;
unique_ptr<Foo> ptr(new Foo); …Run Code Online (Sandbox Code Playgroud) 在使用C++ 11和Boost.Asio的应用程序中,我开始使用lambda函数和一个std::unique_ptr.我想将此unique_ptr的所有权转移到lambda.您无法通过值捕获unique_ptr,因为此类不提供复制构造函数.通过引用捕获它也是愚蠢的,因为我确实希望转让所有权.
我决定用它std::bind来传递unique_ptr这个lambda函数的最后一个参数.我std::move用来给这个lambda提供一个r值引用.稍后我会将这个r值移动到std::unique_ptr(lambda的本地).我遇到了一些可怕的gcc错误,并且想知道我在代码中错过了什么.
这是包含我丑陋的非工作技巧的代码:
void NetworkClient::start()
{
// Avoid the naggle algorithm on packets.
ip::tcp::no_delay optionNoDelay(true);
socket_.set_option(optionNoDelay);
// Lambda function that receive a packet header.
std::function<void (const boost::system::error_code& error, std::size_t bytesTransfered)> receiveHeaderHandler =
[this, &receiveHeaderHandler] (const boost::system::error_code& error, std::size_t bytesTransfered)
{
if (error)
{
std::cout << LogType::ERROR << "Error while receiving a packet header" << std::endl;
}
if (bytesTransfered < 6)
{
std::cout << LogType::ERROR << …Run Code Online (Sandbox Code Playgroud) 我看到 C++11 文档 ( http://en.cppreference.com/w/cpp/language/lambda ) 中的 lambda 表达式声明支持按值捕获和引用,但不支持右值引用。我能找到的与此相关的最接近的问题是:How to capture a unique_ptr into a lambda expression? ,但我的用例似乎不需要使用std::bind.
#include <iostream>
#include <memory>
class Foo
{
public:
explicit Foo(int value = 0) : mValue(value) {}
// The following items are provided just to be explicit
Foo(Foo &&other) = default;
Foo &operator=(Foo &&other) = default;
Foo(const Foo &other) = delete;
Foo &operator=(const Foo &other) = delete;
~Foo() {}
int mValue;
};
void bar(std::unique_ptr<Foo> f)
{
std::cout << "bar: …Run Code Online (Sandbox Code Playgroud) 执行这个简单的代码片段:
{
QModelIndexList sel = ui->tableView->selectionModel()->selectedRows(0);
sel.at(0).isValid(); // To prevent removing the previous line by optimization
}
Run Code Online (Sandbox Code Playgroud)
当所选行的数量约为一百万时,需要超过30秒.QModelIndex列表的构造几乎是立即的,但破坏需要永远.花在这个函数上的时间是:
template <typename T>
Q_INLINE_TEMPLATE void QList<T>::node_destruct(Node *from, Node *to)
{
if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic)
while(from != to) --to, delete reinterpret_cast<T*>(to->v);
else if (QTypeInfo<T>::isComplex)
while (from != to) --to, reinterpret_cast<T*>(to)->~T();
}
Run Code Online (Sandbox Code Playgroud)
有人有解决方案吗?有没有办法在没有创建的情况下获取所选行的索引QModelIndexList,或者我可以以某种方式加速破坏?
我需要将 a 移至关闭unique_ptr状态std::function。我在 C++14 中使用通用 lambda 捕获。
auto ptr = make_unique<Foo>();
// Works.
auto lambda = [p = move(ptr)] { };
// This does not compile.
std::function<void()> func = [p = move(ptr)] { };
Run Code Online (Sandbox Code Playgroud)
它试图将 lambda 捕获复制而不是移动到std::function. 相关错误是:
copy constructor of '' is implicitly deleted because field '' has a deleted copy
constructor
std::function<void()> func = [p = move(ptr)] { };
Run Code Online (Sandbox Code Playgroud)
这里的例子会让这看起来可行。
请注意,这里的答案只是重复 isocpp.org 上的示例。
我可以移动到 ashared_ptr如下:
shared_ptr<Foo> …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个可调用的对象,它基本上有一个绑定的unique_ptr内部.我已经阅读了如何将unique_ptr捕获到lambda表达式中?
但我无法进一步传递lambda.以下代码无法编译,表明unique_ptr正在进行复制.我不太明白为什么要尝试复制unique_ptr.
#include <iostream>
#include <memory>
#include <functional>
using namespace std;
void f(std::function<void(int)> unary) {
unary(42);
unary(1337);
}
struct A{
void woof(int i) {cout<< "woof " << i << "\n";}
};
int main(){
auto another_unique = make_unique<A>();
auto bound_p = [ p = move(another_unique) ] (int i) {p->woof(i);};
bound_p(5);
f( bound_p ); // does not compute
}
Run Code Online (Sandbox Code Playgroud)
我也尝试在调用中定义lambda内联f,这样它就可以成为一个临时对象了,它可以被移入f.但错误是一样的.
是否可以将这样的对象绑定/包装成callables并传递它们?
我的用例取决于unique_ptr,但我怀疑任何删除副本c'tor的对象都会出现同样的问题.如果我错了,请告诉我或编辑主题不太通用.