是否可以返回不可移动,不可复制类型的实例? [英] Is it possible to return an instance of a non-movable, non-copyable type?

查看:86
本文介绍了是否可以返回不可移动,不可复制类型的实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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::mutexstd::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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆