C++11 防止创建临时对象
我有一个五年前在这里被问到的问题: 我再次问这个问题的原因是,我对C++11和C++14技术特别感兴趣,这些技术可以防止临时表的构造 一个想法是使用“此*的右值引用”:C++11 防止创建临时对象,c++11,c++14,C++11,C++14,我有一个五年前在这里被问到的问题: 我再次问这个问题的原因是,我对C++11和C++14技术特别感兴趣,这些技术可以防止临时表的构造 一个想法是使用“此*的右值引用”: class ScopedLock { 公众: void enable()&&=delete; void enable()& { 是否启用=真; } ~ScopedLock() { 如果(!已启用){ std::cerr这里是两个伟大答案的C++11版本。我不应该为此获得太多的赞扬,因此考虑投票支持原始答案 用户1773602的
class ScopedLock
{
公众:
void enable()&&=delete;
void enable()&
{
是否启用=真;
}
~ScopedLock()
{
如果(!已启用){
std::cerr这里是两个伟大答案的C++11版本。我不应该为此获得太多的赞扬,因此考虑投票支持原始答案
用户1773602的
其思想是定义一个与类同名的已删除函数:
class ScopedLock {
// ...
};
void ScopedLock(...) = delete;
这种用法不常见,可能(非常?)不方便:
class ScopedLock a; // OK :-| but requires keyword 'class'
ScopedLock b; // Compiler error :-(
ScopedLock(); // Compiler error :-)
的
如果您不介意出现运行时错误(像OP一样)而不是编译时错误,那么您可以试试这个
基本思想是,与ScopedLock
构造函数的参数的临时绑定将在ScopedLock
对象之前或之后销毁,具体取决于后者是否为临时绑定
class ScopedLock {
bool flag_ = true;
struct Flag {
bool* flag;
~Flag() {
*flag = false;
}
};
public:
ScopedLock(Flag&& f = Flag()) {
f.flag = &flag_;
}
~ScopedLock() {
if (flag_) {
std::cerr << "ScopedLock misuse\n.";
std::terminate();
}
}
};
如果编写void enable()&&=delete;
,实际上会阻止ScopedLock().enable();
之类的事情进行编译。但是,它不会阻止ScopedLock()的编译
来自编译。很好的观点。肯定是一个改进。如果有可能向析构函数添加一个右值引用限定符,这个问题就会得到解决。但据我所知,这是不可能的。templatetypename std::detaction::type&as_左值(T&&T){return T;}
然后as_左值(ScopedLock{}).enable()
--因此上述方法不起作用。作为XY问题,您可以将锁与锁定的数据组合在一起。仅通过lock类的实例提供对数据的访问。
class ScopedLock {
bool flag_ = true;
struct Flag {
bool* flag;
~Flag() {
*flag = false;
}
};
public:
ScopedLock(Flag&& f = Flag()) {
f.flag = &flag_;
}
~ScopedLock() {
if (flag_) {
std::cerr << "ScopedLock misuse\n.";
std::terminate();
}
}
};
ScopedLock a; // OK
ScopedLock(); // Runtime error