允许用户向std命名空间添加显式特化.但是,有一些模板我明确禁止专业化.
我可以和不可以使用哪些模板?
我有一个泛型类myClass,有时需要根据用途存储额外的状态信息.这通常用a完成void*,但我想知道我是否可以使用一个,std::unique_ptr<void, void(*)(void*)>以便在类实例被破坏时自动释放内存.问题是我需要使用自定义删除器,因为删除void*会导致未定义的行为.
有没有办法默认构造一个std::unique_ptr<void, void(*)(void*)>,所以我没有先用虚拟删除器构造它,然后在我使用void*状态结构时设置一个真正的删除器?或者是否有更好的方法将状态信息存储在类中?
以下是一些示例代码:
void dummy_deleter(void*) { }
class myClass
{
public:
myClass() : m_extraData(nullptr, &dummy_deleter) { }
// Other functions and members
private:
std::unique_ptr<void, void(*)(void*)> m_extraData;
};
Run Code Online (Sandbox Code Playgroud) 在下面的例子中,如何正确调用~CImpl,但是当需要移动类时,编译器说它有一个不完整的类型?
如果Impl的声明被移动到它工作的标题,我的问题是如何将析构函数调用为好,所以它似乎不是类型不完整,但移动时出现问题.
档案:C.hpp
#include <memory>
class Impl;
class C
{
public:
C();
~C();
C(C&&) = default;
C& operator=(C&&) = default;
std::unique_ptr<Impl> p;
};
Run Code Online (Sandbox Code Playgroud)
档案C.cpp
#include "C.hpp"
#include <iostream>
using namespace std;
class Impl
{
public:
Impl() {}
virtual ~Impl() = default;
virtual void f() = 0;
};
class CImpl: public Impl
{
public:
~CImpl()
{
cout << "~CImpl()" << endl;
}
void f()
{
cout << "f()" << endl;
}
};
C::C():
p(new CImpl())
{}
C::~C()
Run Code Online (Sandbox Code Playgroud)
file:main.cpp
#include <iostream>
#include …Run Code Online (Sandbox Code Playgroud) 我的代码
void build(std::vector<RKD <DivisionSpace> >& roots, ...) {
try {
// using a local lock_guard to lock mtx guarantees unlocking on destruction / exception:
std::lock_guard<std::mutex> lck (mtx);
roots.push_back(RKD<DivisionSpace>(...));
}
catch (const std::bad_alloc&) {
std::cout << "[exception caught when constructing tree]\n";
return;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,实际工作应该连续进行,而不是并行进行.
构造函数RKD可以与其他构造函数并行运行RKD.然而,推回物体std::Vector是一个关键部分,对吗?
我要构建的对象的数量是已知的.在实践中它将在[2,16]范围内.理论上它可以是任何正数.
此外,我对它们将被插入容器的顺序并不感兴趣.
所以我可以这样做:
RKD tree = RKD(...);
mutex_lock(...);
roots.push_back(tree);
Run Code Online (Sandbox Code Playgroud)
然而,这意味着复制,不是吗?
我应该怎么做才能使我的代码并行?
由于这个答案,我决定使用锁(而不仅仅是互斥锁).
以下代码导致内存损坏导致崩溃.我假设这是因为delete pTestStateMachine试图删除未在堆中分配的内存.那是对的吗?
如果是这样,是否意味着QStateMachine::addState(QAbstractState * state)必须始终传递动态分配的内存?不幸的是Qt docs并没有指定任何这样的条件.我在这里错过了什么?
class CTestClass
{
public:
QState m_pTestState;
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QStateMachine *pTestStateMachine;
CTestClass TestClass;
pTestStateMachine = new QStateMachine();
pTestStateMachine->addState(&(TestClass.m_pTestState));
pTestStateMachine->setInitialState(&(TestClass.m_pTestState));
pTestStateMachine->start();
pTestStateMachine->stop();
delete pTestStateMachine;
return a.exec();
}
Run Code Online (Sandbox Code Playgroud) 这不是关于模板构造函数的问题的重复,甚至不是调用继承的模板构造函数.
它具体是关于在unique_ptr <...,...>模板的类实例(?)的子类中调用继承的构造函数.
为了使代码更容易理解,我using在这个例子中使用:
using B = std::unique_ptr<int *, decltype(&::free)>;
class int_ptr : public B {
int_ptr(int *b) : B(b, &::free) { };
};
Run Code Online (Sandbox Code Playgroud)
但编译失败:
In constructor 'int_ptr::int_ptr(int*)':
error: no matching function for call to
'std::unique_ptr<int*, void (*)(void*) throw ()>::unique_ptr(int*&, void (*)(void*) throw ())'
int_ptr(int *b) : B(b, &::free) { };
^
Run Code Online (Sandbox Code Playgroud)
我能想到的缺乏功能匹配的唯一可能原因是存在,throw ()但我不知道该怎么做,或者它甚至是一个问题.可能unique_ptr是没有投掷.
否则,无匹配功能正是我期望匹配的功能.
每次声明unique_ptr的实例时,我都不想继续指定析构函数.在这个答案/sf/answers/1163069981/中有一个很好的选择,但我很想知道我的尝试有什么问题.
当然,在现实生活中,它不是int*我想要包装unique_ptr,而是一些不透明(但不是void*)指针.
我的目的是在范围退出时正确释放来自C API的所有指针.
也许我可以将这些指针限制在带有析构函数的类/结构中,但我看不出它会节省多少.
有了@RSahu的提示,我想出了这个,unique_dptr以避免继续指定析构函数,但作为替代std命名空间中的模板删除函数的替代方法: …
参考嗯,std :: unique_ptr的自定义删除器是如何工作的?
构造函数
std::unique_ptr<ErrorHandling> error_;
RecursiveDescentParser::RecursiveDescentParser(std::string inputStream, bool fileService,
boost::optional<std::string> filePathName, std::ofstream &writer){
if (fileService == true){
error_(new ErrorHandling(fileService, writer)); <---- compiler error
}
else{
error_(new ErrorHandling(fileService, std::ofstream())); <---- compiler error
}
}
Run Code Online (Sandbox Code Playgroud)
编译错误
Error 1 error C2247: 'std::default_delete<_Ty>::operator ()' not accessible because 'std::unique_ptr<_Ty>' uses 'private' to inherit from 'std::_Unique_ptr_base<_Ty,_Dx,_Empty_deleter>'
Run Code Online (Sandbox Code Playgroud)
这里描述的错误原因.
我之所以认为'std::default_delete<_Ty>::operator ()是private因为子类(std::unique_ptr在这种情况下)指定private inheritance我会编写自己的自定义删除器.问题是我对语法和符号成功感到不舒服.
c++ ×7
c++11 ×4
unique-ptr ×2
constructor ×1
inheritance ×1
pimpl-idiom ×1
qt ×1
state ×1
std ×1
templates ×1
vector ×1