gpt4 book ai didi

c++ - 移动 std::shared_ptr 会使程序崩溃

转载 作者:太空狗 更新时间:2023-10-29 23:07:13 25 4
gpt4 key购买 nike

我必须为一项工作构建一个小型 OpenGL 包装器。我试图避免为我的所有类编写复制构造函数和复制赋值。

真正懒惰并且从不写拷贝的一种方法是使用指针,但由于指针是邪恶的,我正在尝试专门使用 std::shared_ptr

问题是通过使用按值接收 std::shared_ptr 的构造函数,我的程序崩溃了,并且在使用完美转发时,它仅在我传递左值时有效。

// this class doesn't have any default, copy constructors.
class Dep
{
Dep(std::string path, GLenum type);
};

class Program
{
std::shared_ptr<Dep> dep1;
std::shared_ptr<Dep> dep2;

(...)

我尝试了两种不同的构造函数:

template <class T, class = typename std::enable_if<std::is_constructible<std::shared_ptr<Dep>, T>::value>::type>
Program(T&& dep1, T&& dep2)
: dep1(std::forward<T>(dep1)), dep2(std::forward<T>(dep2))
{
}

还有一个

Program(std::shared_ptr<Dep> dep1, std::shared_ptr<Dep> dep2)
: dep1(std::move(dep1)), dep2(std::move(dep2))
{
}

我想做的是能够传递左值或右值共享指针,但它不起作用,每次都会崩溃,除非我在前向指针上使用左值。

// passing these work on the std::forward one, but that's the only case it works
// if i try to use std::make_shared as parameter (for rvalue) it crashes on both
// the std::move and std::forward ones.
auto vs = std::make_shared<GLShader>("TriangleVS.glsl", GL_VERTEX_SHADER);
auto fs = std::make_shared<GLShader>("TriangleFS.glsl", GL_FRAGMENT_SHADER);

总结:std::forward 上的左值有效。 std::forward 上的右值不起作用。 std::move 上的左值或右值不起作用。它只是在调用 std::shared_ptr 构造函数时挂起程序(在 Program 构造函数内)。

我看了 Scott Mayers 的通用引用演讲,我以为我理解了这一点,而这发生在我身上。

最佳答案

我没有发现此代码有任何问题,并且它在 http://ideone.com/jlShgB 上测试正常 也是:

#include <memory>
#include <utility>
#include <string>
#include <cassert>

enum GLenum { foo };

// this class doesn't have any default, copy constructors.
struct Dep
{
Dep(std::string path, GLenum type) {}
Dep() = delete;
Dep(Dep const&) = delete;
};

struct Program
{
std::shared_ptr<Dep> dep1;
std::shared_ptr<Dep> dep2;

#if 1
template <class T, class = typename std::enable_if<std::is_constructible<std::shared_ptr<Dep>, T>::value>::type>
Program(T&& dep1, T&& dep2)
: dep1(std::forward<T>(dep1)), dep2(std::forward<T>(dep2))
{
}
#else
Program(std::shared_ptr<Dep> dep1, std::shared_ptr<Dep> dep2)
: dep1(std::move(dep1)), dep2(std::move(dep2))
{
}
#endif
};

int main()
{
auto dep1 = std::make_shared<Dep>("dep1", foo);
auto dep2 = std::make_shared<Dep>("dep2", foo);
Program p(std::move(dep1), std::move(dep2));

assert(!dep1 && !dep2);
}

当然,如果您将 #if 1 更改为 #if 0,断言将引发异常,因为 dep1/dep2 不会被移出。

这让我怀疑其他地方的另一个问题。如果您可以隔离出现问题的 SSCCE,请告诉我。

关于c++ - 移动 std::shared_ptr 会使程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13387082/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com