如果我可以*从代码中删除所有原始指针,因为使用它们可能不是线程安全的,并且设计的意图不明确(可选值,所有权等).但有时候不使用指针并不容易.例如,我们倾向于在多态类型的容器中使用指针作为基类型:
class A : noncopyable { ... };
class B : public A { ... };
std::vector<A*> v;
v.emplace_back(new B);
// temporary container for some operation
std::vector<A*> selected;
if(check())
selected.emplace_back(v.front());
Run Code Online (Sandbox Code Playgroud)
关于上面的代码你能说些什么?谁是老板?它是共享所有权吗?这就是为什么我们应该这样做v:
std::vector<std::unique_ptr<A>> v;
v.emplace_back(make_unique<B>());
Run Code Online (Sandbox Code Playgroud)
现在很明显v拥有对象,但我仍然不喜欢它selected有一个原始指针,使我的设计不直观.查看标准C++库我认为只有一种类型可以完成这项工作 - std :: reference_wrapper:
std::vector<std::unique_ptr<A>> v;
v.emplace_back(make_unique<B>());
// temporary container for some operation
std::vector<std::reference_wrapper<A>> selected;
if(check())
selected.emplace_back(*v.front());
Run Code Online (Sandbox Code Playgroud)
你觉得那段代码怎么样?这是一个好习惯吗?我知道std::ref()并且std::cref主要用于模板的地方,但似乎在这里我们也可以使用它来清楚地说明我们的设计意图.我看到的唯一问题是我必须取消引用std::reference_wrapper,get()并且没有operator*()或者operator->()内部具有相同的接口,就像在容器中一样unique_ptr.我应该自己写类似的东西吗?或者也许在未来的C++版本中可以为这样的用例扩展reference_wrapper?请分享您的反馈意见.
编辑:我改变了代码示例,以更好地显示意图.
从一段时间以来,我们可以听到很多价值,因为semanthics在C++中非常重要(即这里和这里).我知道我们应该使用它,特别是当我们打算复制函数体内的值时.所以我认为这样的用法是公平的:
void foo(std::string txt) { my_container.emplace_back(move(txt)); }
Run Code Online (Sandbox Code Playgroud)
但是我没有找到任何建议,如果我必须通过一个大型项目中的大型函数树传递该参数.例如:
void bar(std::string txt) { foo(move(txt)); /* more actions */ }
void boo(std::string txt) { bar(move(txt)); /* more actions */ }
Run Code Online (Sandbox Code Playgroud)
有人可以推荐在这种情况下做什么吗?我们应该保持价值语义,并希望编译器优化器能够限制移动操作的数量或在任何地方使用const引用,并且最后只有一个副本?或许,正如在许多情况下在C++中,它取决于(即复制和移动特定类型的成本)?:-)
我有一个已经在cmake下建立的大项目.我正在寻找一种方法来获取源文件列表及其相关的头文件来创建一个新目标(在Emacs的示例etags中).我试图自己找到答案,但似乎并不那么容易.
理想的灵魂将是这样的:
add_executable(my_project <some list of source files and libraries defined in different directories>)
add_custom_target(tags
COMMAND etags <list of all *.cpp and *.h files used in 'my_project' target>
DEPENDS <list of all *.cpp and *h used in 'my_project' target>
COMMENT "Creates source code tags for Emacs")
Run Code Online (Sandbox Code Playgroud)
您是否知道如何使'tags'目标从'my_project'目标导入所有依赖项而无需重写所有目录中的所有cmake配置文件?