【发布时间】:2015-12-14 09:50:24
【问题描述】:
在 VS2013 更新 5 中,我得到了这个:
class Lock
{
public:
Lock(CriticalSection& cs) : cs_(cs)
{}
Lock(const Lock&) = delete;
Lock(Lock&&) = delete;
Lock& operator=(const Lock&) = delete;
Lock& operator=(Lock&&) = delete;
~Lock()
{
LeaveCriticalSection(&(cs_.cs_));
}
private:
CriticalSection& cs_;
};
class CriticalSection
{
CRITICAL_SECTION cs_;
public:
CriticalSection(const CriticalSection&) = delete;
CriticalSection& operator=(const CriticalSection&) = delete;
CriticalSection(CriticalSection&&) = delete;
CriticalSection& operator=(CriticalSection&&) = delete;
CriticalSection()
{
InitializeCriticalSection(&cs_);
}
~CriticalSection()
{
DeleteCriticalSection(&cs_);
}
// Usage: auto lock = criticalSection.MakeLock();
Lock MakeLock()
{
EnterCriticalSection(&cs_);
return Lock(*this);
}
}
MakeLock 返回一个不可移动、不可复制类型的实例。这似乎工作正常。但是,Visual Studio intellisense 确实用红色强调了返回,并警告说 Lock 的移动构造函数不能被引用,因为它是一个已删除的函数。
我试图了解它为什么有效,以及它是符合标准的 C++ 还是只是 MSVC 特有的东西。我猜返回是有效的,因为构造返回值的需要可以被优化掉,所以智能感知警告会警告一些实际上不会发生的事情。
我想我在某处读到过,C++ 将标准化以确保始终会发生返回值优化。
那么,这是符合 C++ 标准的代码吗?它会在未来的编译器中继续工作吗?
附:我意识到std::mutex 和std::lock_guard 可能会取代它。
【问题讨论】:
-
标准 C++ 中的代码格式不正确,尽管有 proposed extension 可以使代码按预期运行。
-
这似乎表明该扩展 (P0135R0) 已获得批准。我想我需要等待 C++17 编译器。 isocpp.org/blog/2015/11/kona-standards-meeting-trip-report
-
不,P0135 处于早期阶段,离“批准”还很远。虽然它似乎很受欢迎,但它离最终形式还很遥远。供应商通常只执行明显的缺陷报告(甚至在批准之前),或者实际工作草案中超出上次发布标准的内容。
-
return {*this};而不是return Lock(*this);在 C++17 之前做你想做的事。
标签: c++ language-lawyer