是否可以返回不可移动,不可复制类型的实例? [英] Is it possible to return an instance of a non-movable, non-copyable type?
问题描述
在VS2013更新5中,我知道了这一点:
In VS2013 update 5, I've got this:
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的move构造函数.
MakeLock
returns an instance of a non-movable, non-copyable type. And this seems to work ok. But, Visual Studio intellisense does underline the return in red with a warning that Lock's move constructor can't be referenced as it is a deleted function.
我试图理解为什么这样做,以及它是否符合标准的C ++或MSVC特有的功能.我猜想返回是有效的,因为可以优化构造返回值的需要,因此,智能感知警告会警告实际上没有发生的某些事情.
I'm trying to understand why this works and if it is standard conforming C++ or just something peculiar to MSVC. I guess the return works because the need to construct the returned value can be optimized away, so the intellisense warning warns about something that doesn't - in practice - actually happen.
我想我读过某个地方,C ++将在确保始终进行返回值优化方面进行标准化.
I think I read somewhere that that C++ would standardize on ensuring that return value optimizations would always happen.
那么,这是符合C ++的代码,它将在将来的编译器中继续使用吗?
So, is this conforming C++ code and will it continue to work in future compilers?
P.S.我意识到std::mutex
和std::lock_guard
可能会取代它.
P.S. I realize std::mutex
and a std::lock_guard
might replace this.
推荐答案
如果编译成功,那就是编译器中的错误. VC2015正确无法编译它.
If that compiles, it is a bug in the compiler. VC2015 correctly fails to compile it.
class Foo
{
public:
Foo() {}
Foo(const Foo&) = delete;
Foo(Foo&&) = delete;
};
Foo Bar()
{
return Foo();
}
给我:
xxx.cpp(327): error C2280: 'Foo::Foo(Foo &&)': attempting to reference a deleted function
和g ++ 4.9说:
and g++ 4.9 says:
error : use of deleted function 'Foo::Foo(Foo&&)'
该标准非常明确,即使RVO表示未调用它,复制构造函数或move构造函数也必须存在并且可以访问.
The standard is very clear that a copy constructor or move constructor must exist and be accessible, even if RVO means it is not invoked.
这篇关于是否可以返回不可移动,不可复制类型的实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!