为什么std::make_unique标准C++ 11库中没有函数模板?我发现
std::unique_ptr<SomeUserDefinedType> p(new SomeUserDefinedType(1, 2, 3));
Run Code Online (Sandbox Code Playgroud)
有点冗长.以下不是更好吗?
auto p = std::make_unique<SomeUserDefinedType>(1, 2, 3);
Run Code Online (Sandbox Code Playgroud)
这隐藏得new很好,只提到一次类型.
无论如何,这是我尝试实现make_unique:
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
Run Code Online (Sandbox Code Playgroud)
我花了很std::forward长时间来编译这些东西,但我不确定它是否正确.是吗?究竟是什么std::forward<Args>(args)...意思?编译器对此做了什么?
有关智能指针的MSDN页面包含有关在参数列表中创建智能指针的提升警告:
始终在单独的代码行上创建智能指针,从不在参数列表中创建智能指针,以便由于某些参数列表分配规则而不会发生细微的资源泄漏.
它所指的参数列表分配规则是什么?在什么情况下会发生资源泄漏?
Herb Sutter提出了一个简单的实现make_unique():http://herbsutter.com/gotw/_102/
这里是:
template<typename T, typename ...Args>
std::unique_ptr<T> make_unique( Args&& ...args )
{
return std::unique_ptr<T>( new T( std::forward<Args>(args)... ) );
}
Run Code Online (Sandbox Code Playgroud)
我的问题是可变参数模板还不是VS2012的一部分,所以我不能按原样使用这个代码.
有没有一种可维护的方法在VS2012中写这个不会涉及使用不同的args计数复制粘贴相同的函数?
由于std::unique_ptr提供了一种避免内存泄漏并确保异常安全的便捷方法,因此传递它们而不是原始指针是明智的.因此,人们可能想要具有签名的(成员)函数
std::unique_ptr<some_type> foo(some data);
Run Code Online (Sandbox Code Playgroud)
不幸的是,在实现这样的功能时,不能简单地
std::unique_ptr<some_type> foo(some data)
{
return { new some_type(data) }; // error
}
Run Code Online (Sandbox Code Playgroud)
但必须改为
std::unique_ptr<some_type> foo(some data)
{
return std::move( std::unique_ptr<some_type>( new some_type(data) ) ); // awkward
}
Run Code Online (Sandbox Code Playgroud)
因为构造函数unique_ptr::unique_ptr(pointer)是explicit.这个构造函数背后的原因是explicit什么?
构造函数的一个动机explicit是防止意外的隐式类型转换.但是,由于unique_ptr不能通过价值传递,这应该不是一个真正的问题,是吗?
我使用 CentOS 6.6 (gcc 4.4.7) 并使用 Boost.Asio (1.41) 进行开发。我希望 io_servicerun()在m启动时调用管理器对象中的成员函数。我试图编译的代码如下所示:
#include <memory>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
boost::asio::io_service io;
std::unique_ptr<manager> m;
m = std::make_unique<manager>;
io.post(boost::bind(&manager::run, &m));
Run Code Online (Sandbox Code Playgroud)
gcc 对boost::bind声明进行了匹配,其中包括:
/usr/include/boost/bind/mem_fn_template.hpp:40: error: pointer to
member type ‘void (manager::)()’ incompatible with object type
‘std::unique_ptr<manager, std::default_delete<manager> >’
Run Code Online (Sandbox Code Playgroud)
我想在这里做什么?
manager 对象只会知道计时器;一个了解 io_service 的单独对象稍后将被添加到其构造函数中。但我们的想法是manager::run()创建一组初始计时器来引导系统。
澄清:
我的想法是,外部代码块管理 的生命周期,m下一条语句将是io.run(). 外部代码将m在io.run()返回时销毁。因此,为mto传递原始引用io是合适的。但我是一个现代 C++ 新手,在这里可能会偏离基础。
是否可以用来std:fill填充unique_ptrs 数组?目的是为不同的对象提供不同的指针,这些对象用相同的参数初始化.
例如:
std::unique_ptr<int> ar[3];
std::fill(ar.begin(), ar.end(), make_unique_for_each_element_somehow<int>(1));
Run Code Online (Sandbox Code Playgroud) SO上的一个帖子说扩展std是UB(好吧,除非你当然是标准作者).但不时,std幸福地延长.什么时候可以这样做?
我试图从"设计模式"编译一个例子,我面临以下问题:
我有一个基类MapSite:
class MapSite{
public:
MapSite();
virtual ~MapSite();
virtual void Enter() = 0;
};
Run Code Online (Sandbox Code Playgroud)
和派生类房间:
class Room : public MapSite final{
private:
unsigned int room_number;
public:
Room(unsigned int rn) : room_number(rn) {};
virtual void Enter() override;
};
Run Code Online (Sandbox Code Playgroud)
从另一个类我想调用该函数
virtual std::unique_ptr<Room> MakeRoom(unsigned int n) {return make_unique<Room(n)>();}
Run Code Online (Sandbox Code Playgroud)
当我这样做时,我收到以下错误:
error: temporary of non-literal type ‘Room’ in a constant expression
virtual std::unique_ptr<Room> MakeRoom(unsigned int n) {return unique::make_unique<Room(n)>();}
Run Code Online (Sandbox Code Playgroud)
所以我认为问题可能是构造函数必须constexpr从另一个函数调用Room的构造函数,但是将构造函数设置为:
constexpr Room(unsigned int rn) : room_number(rn) {};
Run Code Online (Sandbox Code Playgroud)
会产生这个错误:
error: call to non-constexpr function ‘MapSite::MapSite()’ …Run Code Online (Sandbox Code Playgroud) 我正在c ++ 11(gcc 4.8.2)中开发c ++项目。最近我发现unique_ptr对我有用。不幸的是,我无法std::make_unique在我的环境中使用该功能。所以,我想的延迟初始化unique_ptr使用std::move。
实际上,以下代码有效,我对自己没有信心。您能对初始化a的更好方法提供任何意见unique_ptr吗?我认为我的初始化有点多余。
class AppData {
public:
AppData(int id):_id(id){};
int _id;
void print() { std::cout << "id is " << _id << std::endl; };
};
class Test {
public:
Test(){};
~Test(){};
void test();
std::unique_ptr<AppData> p_data;
};
void Test::test() {
// I am concerned with this part
std::unique_ptr<AppData> p(new AppData(3));
p_data = std::move(p);
p_data->print();
}
int main() {
Test t;
t.test();
return 0;
}
Run Code Online (Sandbox Code Playgroud) 这是我遇到的一个问题的最小例子,我无法弄清楚我应该如何解决它:
#include <vector>
#include <memory>
class Thing {
};
class App {
public:
std::vector<std::unique_ptr<Thing>> thingVec;
void add_thing(Thing*);
};
void App::add_thing(Thing* thing) {
thingVec.push_back(std::unique_ptr<Thing>(thing));
}
int main() {
App app;
Thing thing;
app.add_thing(&thing);
}
Run Code Online (Sandbox Code Playgroud)
这个编译并运行没有任何问题,但是,当到达主要,段错误和吐出的结尾时:
Error in `/path/testapp': free(): invalid pointer: 0x00007fff97118070 ***
Run Code Online (Sandbox Code Playgroud)
任何可能的帮助?我想存储(唯一)指针的原因是Thing通常会派生出来.
编辑:一个有效的解决方案:
#include <vector>
#include <memory>
class Thing {
};
class App {
public:
std::vector<std::unique_ptr<Thing>> thingVec;
void add_thing(Thing*);
};
void App::add_thing(Thing* thing) {
thingVec.push_back(std::unique_ptr<Thing>(thing));
}
int main() {
App app;
Thing* thing = new Thing;
app.add_thing(thing);
}
Run Code Online (Sandbox Code Playgroud)
但根据我的理解,我应该能够完全避免使用new,并使用make_unique?我似乎无法找到make_unique实际定义的位置. …
c++ ×10
c++11 ×8
unique-ptr ×5
c++14 ×2
arrays ×1
boost ×1
boost-asio ×1
boost-bind ×1
constexpr ×1
constructor ×1
gcc ×1
namespaces ×1
std ×1
templates ×1