根据文件,其中说
我们已经在 return 语句中对本地值和函数参数进行了隐式移动。下面的代码编译得很好:
Run Code Online (Sandbox Code Playgroud)std::unique_ptr<T> f(std::unique_ptr<T> ptr) { return ptr; }
但是,下面的代码无法编译
Run Code Online (Sandbox Code Playgroud)std::unique_ptr<T> f(std::unique_ptr<T> && ptr) { return ptr; }
相反,您必须输入
Run Code Online (Sandbox Code Playgroud)std::unique_ptr<T> f(std::unique_ptr<T> && ptr) { return std::move(ptr); }
这是我的问题:
1.确实没有复制构造函数std::unique_ptr<T>
,不应该有一个函数可以接受声明为 的参数std::unique_ptr<T>
。请参阅此代码片段,它无法编译。
#include <memory>
class FooImage{};
std::unique_ptr<FooImage> FoolFunc(std::unique_ptr<FooImage> foo)
{
return foo;
}
int main()
{
std::unique_ptr<FooImage> uniq_ptr(new FooImage);
FoolFunc(uniq_ptr);
}
Run Code Online (Sandbox Code Playgroud)
2.为什么
std::unique_ptr<T> f(std::unique_ptr<T> && ptr) {
return ptr;
}
Run Code Online (Sandbox Code Playgroud)
不编译?
有人可以解释一下这个问题吗?
我最初在创建类时遇到问题map
,在一些帮助下我意识到我实际上需要一个map<string, unique_ptr<myclass>>
.
更准确地说:
std::map<std::string, unique_ptr<ancestor>>
我的实例的所有权(我希望如此)。map
,然后仅在运行时引用它;出于所有实际目的,初始化它后(这是一个复杂的事情,涉及读取配置文件),它可能会变成
const
.我需要实现的一个最小的例子是:
#include <iostream>
#include <string>
#include <memory>
#include <map>
class generic {
std::string _name;
public:
generic(std::string name) : _name(name) {}
virtual ~generic() = default;
virtual std::string name() { return _name; }
virtual std::string value() { return "no value in generic"; }
};
template <class T> class special : public generic {
T _value;
public:
special(std::string name, T value) : generic(name), _value(value) …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用自定义函数来删除 unique_ptr 。但编译器给了我错误。不知怎的,我怀疑这是因为我的删除器不是类类型。但我发誓它以前可以使用函数,我曾经插入 C 函数就很好了。什么是真正的交易?
#include <cstdio>
#include <memory>
#include <utility>
using cTYPE = struct {
int a;
};
void delete_wrapper(cTYPE* ptr)
{
return free(ptr);
}
cTYPE* new_wrapper()
{
return static_cast<cTYPE*>(malloc(sizeof(cTYPE)));
}
int main()
{
auto foo = []() {
using tmp_storage_type = std::unique_ptr<cTYPE, decltype(delete_wrapper)>;
static tmp_storage_type obj;
obj = tmp_storage_type{ new_wrapper(), delete_wrapper };
};
foo();
}
Run Code Online (Sandbox Code Playgroud)
错误(其中,clang 在这里给出了更好的错误):
<source>:23:33: note: in instantiation of template class 'std::unique_ptr<cTYPE, void (cTYPE *)>' requested here
static tmp_storage_type obj;
^
<source>:24:15: error: no …
Run Code Online (Sandbox Code Playgroud) 例如:
// Example program
#include <iostream>
#include <string>
class abstract_class
{
public:
abstract_class() = default;
~abstract_class() = default;
virtual void read() = 0;
};
int main()
{
std::unique_ptr<abstract_class> x;
std::cout << "Hello, " << "!\n";
}
Run Code Online (Sandbox Code Playgroud)
我认为抽象类有这些限制
抽象类不能用于:
变量或成员数据
参数类型<------------
函数返回类型
显式转换类型
在上面的代码中,我们使用抽象类作为模板参数,那么为什么这不是一个错误呢?
我想通过以下方式管理 WinAPI 函数对std::unique_ptr
:
#include <memory>
int* __stdcall construct(){ return new int{5}; }
void __stdcall destruct(int* v){ delete v; }
int main() {
using Ptr = std::unique_ptr<int, void(&)(int*)>;
Ptr v(construct(), destruct);
}
Run Code Online (Sandbox Code Playgroud)
当我使用 MSVC 19.33 构建 64 位二进制文件时,代码可以正常工作。如果我构建 32 位二进制文件,则会出现错误。
example.cpp
<source>(8): error C2660: 'std::unique_ptr<int,void (__cdecl &)(int *)>::unique_ptr': function does not take 2 arguments
C:/data/msvc/14.33.31631/include\memory(3291): note: see declaration of 'std::unique_ptr<int,void (__cdecl &)(int *)>::unique_ptr'
Compiler returned: 2
Run Code Online (Sandbox Code Playgroud)
__stdcall
如果我明确命名in ,它适用于两者std::unique_ptr<int, void(__stdcall&)(int*)>
,所以我假设它是函数签名的一部分。
为什么 32 位和 64 位会有这种差异?这是编译器中的错误吗?
假设我有一个从某些 API 生成的数据向量。它仅用于绘图。
vector<double> LineData = generateData();
Run Code Online (Sandbox Code Playgroud)
我还有一个类可以进行绘图和管理数据
class LineChart
{
public:
LineChart(vector* data):m_data{data}{}
vector<double> *m_data;
void plot();
};
LineChart lc {&LineData}
Run Code Online (Sandbox Code Playgroud)
由于向量仅用于绘图,因此我希望该类拥有完全所有权。所以我想将原始指针更改为 unique_ptr。
通常,unique_ptr 是从 new 或 make_unique 创建的,而不是现有对象。我可以复制该向量,然后将其移至班级。
unique_ptr<vector> data = make_unique<vector>(LineData)
Run Code Online (Sandbox Code Playgroud)
但是复制向量会产生不必要的开销,因为我已经有了数据。此外,原始向量在堆栈上变得重复并且不执行任何操作。
那么在这种情况下,是否有一些有效的方法将现有对象的所有权传递给类?最好的做法是什么?
我想打印一个std :: unique_ptr,它是Bar的类成员.但是,以下代码不起作用请参阅我对流<< bar.foo_unique(); 我想我应该改变我的foo_unique()访问器,但我不知道怎么做.
#include <iostream>
#include <memory>
class Foo
{
public:
Foo() : n_(1) {}
int n() const { return n_; }
private:
int n_;
};
std::ostream& operator<< (std::ostream& stream, const Foo& foo);
std::ostream& operator<< (std::ostream& stream, const Foo& foo)
{
stream << foo.n();
return stream;
}
class Bar
{
public:
Bar() : m_(2), foo_(), foo_unique_(std::make_unique<Foo>()) {}
int m() const { return m_; }
const Foo& foo() const { return foo_; }
const std::unique_ptr<Foo>& foo_unique() const { …
Run Code Online (Sandbox Code Playgroud) 所以我使用的自定义矢量容器来自:https://github.com/patr0nus/Vector/blob/master/Vector.h
我正在尝试创建一个指向自定义Class对象的unique_ptr向量.
它曾经失败过:
错误:无法分配类型为'std :: __ 1 :: unique_ptr std :: __ 1 :: default_delete>'的对象,因为其隐式删除了其复制赋值运算符
我通过向vector.h添加以下代码来修复它:
void push_back(T&& val)
{
resize(m_size + 1);
m_container[m_size - 1] = std::move(val);
}
Run Code Online (Sandbox Code Playgroud)
现在,问题是,我无法迭代这个向量和其他功能,如swap
失败:
no matching function for call to 'swap'
swap(*__x4, *__x5);
candidate template ignored: could not match 'tuple' against 'unique_ptr'
swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
Run Code Online (Sandbox Code Playgroud)
我需要一些关于如何解决这些问题的指导.
对于通用标题很抱歉,但我只能描述正在发生的事情.
std::unique_ptr<int> qq() {
int b = 11;
std::unique_ptr<int> f(&b);
return f;
}
int main() {
std::unique_ptr<int> q = qq();
int *p = q.release();
*p = 11;
std::cout << *p << "\n";
std::cout << *p << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出
11
32767 // why not 11?
Run Code Online (Sandbox Code Playgroud)
返回return std::move(f)
结果输出
11
0 // why not 11?
Run Code Online (Sandbox Code Playgroud) 我收到以下错误:
“make_unique”不是“std”的成员
当它编写以下代码时:
std::make_unique()<Obj>(tmp)
我该如何修复它,使其在 c++11 中可以正常工作?
c++ ×10
unique-ptr ×10
c++11 ×3
c++14 ×1
c++20 ×1
class ×1
constructor ×1
dictionary ×1
object ×1
pointers ×1
stdcall ×1
vector ×1
visual-c++ ×1
winapi ×1