相关疑难解决方法(0)

什么是移动语义?

我刚刚听完了Scott Meyers关于C++ 0x的软件工程电台播客采访.大多数新功能对我来说都很有意义,我现在对C++ 0x感到兴奋,除了一个.我仍然没有得到移动语义 ......它们究竟是什么?

c++ c++-faq move-semantics c++11

1614
推荐指数
11
解决办法
39万
查看次数

T &&(双&符号)在C++ 11中意味着什么?

我一直在研究C++ 11的一些新功能,我注意到的是在声明变量时使用的双符号,例如T&& var.

首先,这只野兽叫什么?我希望谷歌允许我们搜索这样的标点符号.

究竟是什么意思?

乍一看,它似乎是一个双重参考(如C风格的双指针T** var),但我很难想到一个用例.

c++ c++-faq rvalue-reference perfect-forwarding c++11

747
推荐指数
4
解决办法
18万
查看次数

如何将std :: unique_ptr传递给函数

我怎样才能将std::unique_ptr函数传递给函数?可以说我有以下课程:

class A
{
public:
    A(int val)
    {
        _val = val;
    }

    int GetVal() { return _val; }
private:
    int _val;
};
Run Code Online (Sandbox Code Playgroud)

以下内容无法编译:

void MyFunc(unique_ptr<A> arg)
{
    cout << arg->GetVal() << endl;
}

int main(int argc, char* argv[])
{
    unique_ptr<A> ptr = unique_ptr<A>(new A(1234));
    MyFunc(ptr);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

为什么我不能传入std::unique_ptr函数?当然这是构造的主要目的吗?或者C++委员会是否打算让我回到原始的C风格指针并将其传递给它:

MyFunc(&(*ptr)); 
Run Code Online (Sandbox Code Playgroud)

最奇怪的是,为什么这是一种传递它的好方法?看起来非常不一致:

MyFunc(unique_ptr<A>(new A(1234)));
Run Code Online (Sandbox Code Playgroud)

c++ unique-ptr c++11

63
推荐指数
5
解决办法
6万
查看次数

unique_ptr到派生类,作为将unique_ptr带到基类的函数的参数

我试图unique_ptr在一个unique_ptr带有基类的函数中使用一个派生类.就像是:

class Base {};

class Derived : public Base {};

void f(unique_ptr<Base> const &base) {}

…

unique_ptr<Derived> derived = unique_ptr<Derived>(new Derived);
f(derived);
Run Code Online (Sandbox Code Playgroud)

如果我正确理解了这个答案,那么这段代码应该可行,但它会导致以下编译错误:

错误C2664:'f':无法将参数1从'std :: unique_ptr <_Ty>'转换为'const std :: unique_ptr <_Ty>&'

IntelliSense:没有合适的用户定义转换,从"std :: unique_ptr <Derived,std :: default_delete <Derived >>"到"const std :: unique_ptr <Base,std :: default_delete <Base >>"存在

如果我改变f采取unique_ptr<Derived> const &derived,它工作正常,但这不是我想要的.

难道我做错了什么?我该怎么做才能解决这个问题?

我正在使用Visual Studio 2012.

c++ unique-ptr c++11 visual-studio-2012

57
推荐指数
3
解决办法
5万
查看次数

"向下转换"unique_ptr <Base>到unique_ptr <Derived>

我有一系列工厂回归unique_ptr<Base>.引擎盖下,虽然,他们所提供的指针各种衍生类型,即unique_ptr<Derived>,unique_ptr<DerivedA>,unique_ptr<DerivedB>

鉴于DerivedA : Derived并且Derived : Base我们有:

unique_ptr<Base> DerivedAFactory() {
    return unique_ptr<Base>(new DerivedA);
}
Run Code Online (Sandbox Code Playgroud)

我需要做的是将指针从返回"转换" unique_ptr<Base>到某个派生级别(不一定是原始的内部级别).用伪代码说明:

unique_ptr<Derived> ptr = static_cast<unique_ptr<Derived>>(DerivedAFactory());
Run Code Online (Sandbox Code Playgroud)

我正在考虑通过从中释放对象unique_ptr,然后使用一个转换原始指针的函数并将其重新分配给另一个unique_ptr所需的风格(release在调用之前由调用者显式完成)来实现这一点:

unique_ptr<Derived> CastToDerived(Base* obj) {
    return unique_ptr<Derived>(static_cast<Derived*>(obj));
}
Run Code Online (Sandbox Code Playgroud)

这是有效的,还是/会有什么时髦吗?


PS.还有一个复杂的问题是,有些工厂驻留在运行时动态加载的DLL中,这意味着我需要确保生成的对象在创建它们的同一个上下文(堆空间)中被销毁.所有权的转移(通常发生在另一个上下文中)必须从原始上下文中提供删除.但除了必须与指针一起提供/转换删除器之外,铸造问题应该是相同的.

c++ smart-pointers factory-pattern unique-ptr c++11

56
推荐指数
1
解决办法
2万
查看次数

通过价值传递与通过右值参考传递

我什么时候应该声明我的功能:

void foo(Widget w);

而不是

void foo(Widget&& w);

假设这是唯一的重载(例如,我选择一个或另一个,不是两个,也没有其他重载).没有涉及模板.假设该函数foo需要所有权Widget(例如const Widget&,不是本讨论的一部分).我对这些情况范围之外的任何答案都不感兴趣.请参阅帖子末尾的附录,了解为什么这些约束是问题的一部分.

我和我的同事可以提出的主要区别是rvalue参考参数强制您明确复制副本.调用者负责制作一个显式副本,然后在std::move需要副本时将其传入.在按值传递的情况下,隐藏了副本的成本:

    //If foo is a pass by value function, calling + making a copy:
    Widget x{};
    foo(x); //Implicit copy
    //Not shown: continues to use x locally

    //If foo is a pass by rvalue reference function, calling + making a copy:
    Widget x{};
    //foo(x); //This would be a compiler error
    auto copy = x; //Explicit copy
    foo(std::move(copy));
    //Not shown: continues …
Run Code Online (Sandbox Code Playgroud)

c++ c++11 c++14

48
推荐指数
5
解决办法
2万
查看次数

如何将unique_ptr捕获到lambda表达式中?

我尝试过以下方法:

std::function<void ()> getAction(std::unique_ptr<MyClass> &&psomething){
    //The caller given ownership of psomething
    return [psomething](){ 
        psomething->do_some_thing();
        //psomething is expected to be released after this point
    };
}
Run Code Online (Sandbox Code Playgroud)

但它没有编译.有任何想法吗?

更新:

AS建议,需要一些新的语法来明确指定我们需要将所有权转移到lambda,我现在考虑以下语法:

std::function<void ()> getAction(std::unique_ptr<MyClass> psomething){
    //The caller given ownership of psomething
    return [auto psomething=move(psomething)](){ 
        psomething->do_some_thing();
        //psomething is expected to be released after this point
    };
}
Run Code Online (Sandbox Code Playgroud)

它会是一个好的候选人吗?

更新1:

我将展示我的实施movecopy如下:

template<typename T>
T copy(const T &t) {
    return t;
}

//process lvalue references
template<typename T>
T move(T &t) {
    return …
Run Code Online (Sandbox Code Playgroud)

c++ lambda unique-ptr c++11

38
推荐指数
4
解决办法
3万
查看次数

如何在构造函数中初始化std :: unique_ptr?

A.hpp:

class A {
  private:
   std::unique_ptr<std::ifstream> file;
  public:
   A(std::string filename);
};
Run Code Online (Sandbox Code Playgroud)

A.cpp:

A::A(std::string filename) {
  this->file(new std::ifstream(filename.c_str()));
}
Run Code Online (Sandbox Code Playgroud)

我得到的错误被抛出:

A.cpp:7:43: error: no match for call to ‘(std::unique_ptr<std::basic_ifstream<char> >) (std::ifstream*)’
Run Code Online (Sandbox Code Playgroud)

有没有人知道为什么会这样?我已经尝试了很多不同的方法让它工作,但无济于事.

c++ smart-pointers ifstream unique-ptr

32
推荐指数
2
解决办法
3万
查看次数

如何将智能指针传递给函数?

将对象传递给函数时,相同的规则是否适用于智能指针以及包含动态内存的其他对象?

例如,当我传递std::vector<std::string>给函数时,我总是考虑以下选项:

  1. 我将改变矢量对象的状态,但我希望在函数完成后反映这些更改,AKA进行复制.

    void function(std::vector<std::string> vec);
    
    Run Code Online (Sandbox Code Playgroud)
  2. 我要改变矢量对象的状态,我确实希望在函数完成后反映这些更改,AKA做出参考.

    void function(std::vector<std::string> & vec);
    
    Run Code Online (Sandbox Code Playgroud)
  3. 这个对象非常大,所以我最好传递一个引用,但是告诉编译器不要让我改变它.

    void function(std::vector<std::string> const& vec);  
    
    Run Code Online (Sandbox Code Playgroud)

现在这与智能指针的逻辑相同吗?什么时候应该考虑移动语义?关于如何通过智能指针的一些指导是我最想要的.

c++ smart-pointers parameter-passing unique-ptr c++11

17
推荐指数
3
解决办法
2万
查看次数

c ++ unique_ptr参数传递

假设我有以下代码:

class B { /* */ };

class A {
    vector<B*> vb;
public:
    void add(B* b) { vb.push_back(b); }
};


int main() {

    A a;
    B* b(new B());
    a.add(b);
}
Run Code Online (Sandbox Code Playgroud)

假设在这种情况下,B*可以处理所有原始指针unique_ptr<B>.

令人惊讶的是,我无法找到如何使用转换此代码unique_ptr.经过几次尝试,我想出了以下代码,它编译:

class A {
    vector<unique_ptr<B>> vb;
public:
    void add(unique_ptr<B> b) { vb.push_back(move(b)); }
};


int main() {

    A a;
    unique_ptr<B> b(new B());
    a.add(move(b));
}
Run Code Online (Sandbox Code Playgroud)

所以我的简单问题是:这是实现它的方式,特别是,这是move(b)唯一的方法吗?(我在想rvalue引用,但我不完全理解它们.)

如果你有一个完整的移动语义解释链接unique_ptr,我无法找到,请不要犹豫,分享它.

编辑根据http://thbecker.net/articles/rvalue_references/section_01.html,我的代码似乎没问题.

实际上,std :: move只是语法糖.对于类X的对象x,move(x)与以下内容相同:

static_cast <X&&>(x)
Run Code Online (Sandbox Code Playgroud)

需要这两个移动函数,因为转换为右值引用:

  1. 防止函数"add"传递值
  2. 使得 …

c++ rvalue-reference unique-ptr c++11

11
推荐指数
2
解决办法
2万
查看次数