我知道RVO主要应用但我可以依靠吗?我有一个函数创建一个FlagContainer类的对象.
class FlagContainer { public: ~FlagContainer() { someItem->flag = true; } private: Item * someItem; } public FlagContainer createFlagContainer() { return FlagContainer(); }
在调用者使用容器之后,必须设置标志.所以我可以用析构函数做到这一点.
{ FlagContainer container = createFlagContainer(); // do something with container }
超出范围时,将调用析构函数.但是我可以确定在createFlagContainer中永远不会调用析构函数吗?有没有办法实现这个目标?
我会使用AVR GCC 4.7.0编译器.
我知道RVO主要应用但我可以依靠吗?
不要依赖RVO来实现逻辑.简而言之,编译程序的人可以使用命令行选项将其关闭.
有没有办法实现这个目标?
令人惊讶的是,标准库已经为您提供了这一功能,因此您无需自行承担实施它的风险(移动构造函数和运算符非常难以正确实现)
std::unique_ptr
使用自定义删除器可以很好地完成工作.
#include#include #include // test type struct X { bool flag = false; }; // a custom deleter that sets a flag on the target struct flag_setter_impl { template void operator()(X* px) const { if (px) { assert(!px->flag); std::cout << "setting flag!" << std::endl; px->flag = true; } } }; // a type of unique_ptr which does not delete, but sets a flag template using flag_setter = std::unique_ptr ; // make a flag_stter for x template auto make_flag_setter(X& x) -> flag_setter { return flag_setter (&x, flag_setter_impl()); } // quick test auto main() -> int { using namespace std; X x; { auto fs1 = make_flag_setter(x); auto fs2 = move(fs1); } return 0; }
但我的目标没有STL
然后不要忘记你的0,3,5规则
#include#include #include // test type struct X { bool flag = false; }; // a custom deleter that sets a flag on the target struct flag_setter_impl { template void operator()(X* px) const { if (px) { assert(!px->flag); std::cout << "setting flag!" << std::endl; px->flag = true; } } }; // a type of unique_ptr which does not delete, but sets a flag template struct flag_setter { flag_setter(X* px) : px(px) {} flag_setter(const flag_setter&) = delete; flag_setter(flag_setter&& r) noexcept : px(r.px) { r.px = nullptr; } flag_setter& operator=(const flag_setter& r) = delete; flag_setter& operator=(flag_setter&& r) { flag_setter tmp(std::move(r)); std::swap(tmp.px, px); return *this; } ~flag_setter() noexcept { flag_setter_impl()(px); } private: X* px; }; // make a flag_stter for x template auto make_flag_setter(X& x) -> flag_setter { return flag_setter (&x); } // quick test auto main() -> int { using namespace std; X x; { auto fs1 = make_flag_setter(x); auto fs2 = move(fs1); } return 0; }