上下文:我有一个队列,支持来自两个不同(/或非)线程的单读/单写,为了强制执行此行为,即一次单读/单写,我需要限制拥有的线程数量队列一次为2(作者已经拥有该队列),我当时正在考虑为队列创建一个shared_ptr,并将编译时已知的最大引用计数设置为2。因此我的问题如下。
问题:有没有一种方法可以实现unique_pointer
具有编译时已知的最大引用计数的共享指针(可能使用 's)?我的情况是max_ref_count = 2
,超过引用计数限制 = 2 应该是编译时错误。
const auto p = std::make_shared<2, double>(2159); //works fine
const auto q = p; // works fine
const auto err1 = p; // does not compile
const auto err2 = q; // does not compile
Run Code Online (Sandbox Code Playgroud) 我有一些管理 unique_ptrs 队列的代码。在其主循环中,它从队列中弹出一个条目,对其执行某些操作,然后允许该元素超出范围并被删除。到目前为止,没有问题。
我想添加一个功能,我们可以将其移动到其他地方,而不是必须删除该元素。问题是只有元素本身知道是否执行此操作或它需要去哪里。
主循环类似于:
std::deque< std::unique_ptr<Object> > queue;
while( !queue.empty() ) {
auto element = std::move( queue.front() );
queue.pop_front();
element->do_something();
element->recycle( std::move(element) ); // ?
}
Run Code Online (Sandbox Code Playgroud)
如果回收不是对象的方法,这将不是问题,但因为它是对象的方法,我不确定它应该是什么样子。通过上面的代码,我会得到类似的东西:
class Object {
public:
virtual void do_something();
virtual void recycle( std::unique_ptr<Object> unique_this ) {
// move unique_this somewhere, or don't and allow it to be deleted
}
};
Run Code Online (Sandbox Code Playgroud)
这安全吗?如果recycle不移动unique_this,它将在它自己的方法之一中删除它(不过在方法的末尾)。那是问题吗?
我想到避免删除这个的一种可能性是让recycle通过左值引用获取unique_ptr,我意识到这有点奇怪。这个想法是,如果它愿意,它会将其移动到某个地方,但如果不这样做,则直到回收返回后该对象才会被删除。不过,它不一定避免在其方法之一中可能删除对象的问题,因为我们必须确保无论我们将其移动到何处都不会立即删除它。
如果这样做不安全,后备计划是让 Object 返回一个回收器(即,一个不是执行回收的 Object 方法的可调用对象)。我认为这应该是可能的,但是考虑到不同的对象想要使用不同的回收器,管理回收器的类型和生命周期会有点混乱。
在我看来,第一个想法(按值传递 unqiue_ptr)是最好的,除非它违反任何规则。这样安全吗?有一个更好的方法吗?
我想unique_ptr
用一个特殊的析构函数重新定义.因此,我使用下面的代码,我试图模仿一些构造函数unique_ptr
.不幸的是,constexpr
构造者拒绝构建,我不知道为什么.
class job_ptr : public unique_ptr<Job>
{
public:
constexpr job_ptr()
: unique_ptr<Job>(), sequencer( nullptr ) {}
constexpr job_ptr( nullptr_t )
: unique_ptr<Job>( nullptr ), sequencer( nullptr ) {}
private:
FIFOSequencer* sequencer;
};
Run Code Online (Sandbox Code Playgroud)
初始化列表中的两个构造函数都被声明constexpr
,但是clang++
考虑constexpr constructor never produces a constant expression
因为non-literal type 'unique_ptr<Job>' cannot be used in a constant expression
.这意味着什么? constexpr
构造函数不能在constexpr
构造函数中使用?
感谢您的任何帮助.
我曾经用新的方式在我的C++项目中分配内存
char* buffer = new char [size];
...
delete[] buffer;
Run Code Online (Sandbox Code Playgroud)
我真的很想继续前进并使用unique_ptr
,就像这样
unique_ptr<char[]>buffer(new char[size]);
Run Code Online (Sandbox Code Playgroud)
但后来我用istream& get (char* s, streamsize n);
它char*
作为第一个参数,所以我该怎么办?我试过投射类型,但失败了.我也知道我可以使用vector<char>
而不是指针,但我真的不想使用它.谢谢!
当我尝试使用for_each算法时,我遇到以下错误std::unique_ptr
.我在下面的profile.h部分放大了它.
奇怪的是,如果我将其更改为能够编译std::shared_ptr
,我怀疑它是按值获取容器的元素,因此不喜欢对unique_ptr
s的引用.但是,我希望它unique_ptr
理想情况下,因为这些任务应该放在ToRun_
容器内,并Completed_
在任务执行后移动到容器,所以shared_ptr
这里没有任何好处.
我得到的错误是:
调用类型为'的对象没有匹配函数(Lambda at Profile.cpp:429:54)'
__f(*__第一);
这是指这行代码:
for_each(ToRun_.begin(), ToRun_.end(), [&os](std::unique_ptr<Task>& e){
if (e){
os << e->getName() <<'\n';
}
});
Run Code Online (Sandbox Code Playgroud)
在我将其转换为使用智能指针之前,我使用了原始指针,我可以保证e->getName()
100%工作.我的困惑是为什么在这种情况下它不起作用?我该怎么做才能使它正常工作?
#include <algorithm>
#include <vector>
#include <map>
#include <iostream>
#include "Task.h"
#include "Global.h" //Where my user defined global functions go
class Profile{
std::vector<std::unique_ptr<Task>>ToRun_;
std::vector<std::unique_ptr<Task>>Completed_;
std::vector<std::string>menu_;
//Ownership of ofstream object
std::ofstream& of_;
public:
Profile (const char* filename, std::ofstream& os, ARAIG_sensors& as);
virtual …
Run Code Online (Sandbox Code Playgroud) #include <memory>
#include <algorithm>
using namespace std;
class A {
public:
unique_ptr<int> u;
A(){}
A(const A& other): u(new int(*other.u)){} // If I comment this out, it works.
// A(A&&){} // This does not help.
};
int main() {
A a;
A b = a;
swap(a, b);
}
Run Code Online (Sandbox Code Playgroud)
此代码不起作用 - 失败,出现模板错误no matching function for call to ‘swap(A&, A&)’
.为什么?删除第二个构造函数会有所帮助,但我需要在其他代码中使用它.我猜测它可以与其他定义的一些构造函数的自动删除相关联,但手动添加移动构造函数也无济于事.我怎样才能解决这个问题?
我无法std::vector<std::unique_ptr<..>>
从函数中移动:MSVC抱怨(C2280)关于尝试引用已删除的函数.
这怎么样?
#include <vector>
#include <iostream>
#include <memory>
using namespace std;
class foo {
public:
int i;
};
vector<unique_ptr<foo>> test() {
vector<unique_ptr<foo>> ret{};
auto f = make_unique<foo>();
f->i = 1;
ret.push_back(move(f));
return move(ret);
}
int main(int argc, char** argv) {
auto t = test();
for (auto j : t) {
// fails here: --^
cout << j->i << endl;
}
getchar();
}
Run Code Online (Sandbox Code Playgroud)
完整的错误消息显示:
'std :: unique_ptr> :: unique_ptr(const std :: unique_ptr <_Ty,std :: default_delete <_Ty >>&)':尝试引用已删除的函数
因此,我试图更改自己的游戏,但发现了无法更改的问题:
我有以下代码:
std::string fileContents = "";
const char* contentsPtr = fileContents.c_str();
Run Code Online (Sandbox Code Playgroud)
我试图做到:
const std::unique_ptr<char> contentsPtr = fileContents.c_str();
Run Code Online (Sandbox Code Playgroud)
由于没有构造函数来进行从char *到unique_ptr的转换,因此它不起作用,那么如何进行此更改?
考虑以下:
unique_ptr<int> foo = make_unique<int>(42);
auto lambda = [bar = move(foo)]()
{
/* Do something with bar */
};
lambda(); // No issues invoking this
cout << "*foo = " << *foo; //Attempts to dereference foo will segfault
Run Code Online (Sandbox Code Playgroud)
捕获诸如unique_ptr之类的东西需要使用std :: move,以保持unique_ptr的唯一性。但是,当我想在销毁lambda之后使用同一智能指针时该怎么办?使用foo将产生段错误,并且bar超出了该范围。
也许撇开lambda的非正统用法,我如何找回unique_ptr?它会永远被困在lambda中吗?
在下面的代码中,我有一个自定义删除器(使用捕获按引用捕获的lambda)std::unique_ptr
。我希望std::unique_ptr
对象的大小应与默认删除器的大小相同(即使用运算符删除),因为捕获是通过引用进行的。我知道无状态函子和lambda(不捕获)不会造成大小损失,那么为什么lambda按引用捕获会引起大小损失呢?预先感谢您的解释。
#include <iostream>
#include <memory>
class X{};
int main()
{
// custom deleter using a state-full lambda
double data[100]{0};
auto lmb_sf = [&data](X* ptr){
// do something
std::cout<<"In custom deleter using a state-full lambda\n";
delete ptr;
};
std::unique_ptr<X,decltype(lmb_sf)> ptr_sf(new X, lmb_sf);
std::cout<<"Size of ptr_sf = "<<sizeof(decltype(ptr_sf))<<"\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出按引用捕获(即使用... lmb_sf = [&data] ...)
Size of ptr_sf = 16
In custom deleter using a state-full lambda
Run Code Online (Sandbox Code Playgroud)
输出按值捕获(即使用... lmb_sf = [data] ...)
Size of ptr_sf = 808 …
Run Code Online (Sandbox Code Playgroud) c++ ×10
unique-ptr ×10
lambda ×3
c++11 ×2
algorithm ×1
c++14 ×1
capture ×1
constexpr ×1
constructor ×1
pointers ×1
shared-ptr ×1
swap ×1