c++ - `auto x = nonmoveable{};` rejected by MSVC but allowed by GCC and clang - Stack Overflow

I am trying to move from T t{ ... }; construction to auto t = T{ ... }; in order to make it consistent

I am trying to move from T t{ ... }; construction to auto t = T{ ... }; in order to make it consistent with function calls like auto p = std::make_unique<T>(...);.

I am however running into issues when T is not move-assignable:

struct nonmoveable {
    nonmoveable(const nonmoveable&) = delete;
    nonmoveable(nonmoveable&&) = delete;
    nonmoveable& operator=(const nonmoveable&) = delete;
    nonmoveable& operator=(nonmoveable&&) = delete;
};

int main() {
    nonmoveable x = {};
    auto y = nonmoveable{};
}

Run on godbolt.

The code above compiles fine on GCC and clang, but fails on MSVC. Changing auto to nonmoveable results in the same error:

(10): error C2280: 'nonmoveable::nonmoveable(nonmoveable &&)': attempting to reference a deleted function (3): note: see declaration of 'nonmoveable::nonmoveable' (3): note: 'nonmoveable::nonmoveable(nonmoveable &&)': function was explicitly deleted

Who is correct according to the standard?

I know that recent revisions introduced a lot of rules regarding copy and move ellisions, but it is not clear to me whether you are allowed to ellide a deleted operation. Pure compiler optimization using the "as if" rule would clearly be forbidden, since the naively equivalent auto y = std::move(x); cannot compile.

I am trying to move from T t{ ... }; construction to auto t = T{ ... }; in order to make it consistent with function calls like auto p = std::make_unique<T>(...);.

I am however running into issues when T is not move-assignable:

struct nonmoveable {
    nonmoveable(const nonmoveable&) = delete;
    nonmoveable(nonmoveable&&) = delete;
    nonmoveable& operator=(const nonmoveable&) = delete;
    nonmoveable& operator=(nonmoveable&&) = delete;
};

int main() {
    nonmoveable x = {};
    auto y = nonmoveable{};
}

Run on godbolt.

The code above compiles fine on GCC and clang, but fails on MSVC. Changing auto to nonmoveable results in the same error:

(10): error C2280: 'nonmoveable::nonmoveable(nonmoveable &&)': attempting to reference a deleted function (3): note: see declaration of 'nonmoveable::nonmoveable' (3): note: 'nonmoveable::nonmoveable(nonmoveable &&)': function was explicitly deleted

Who is correct according to the standard?

I know that recent revisions introduced a lot of rules regarding copy and move ellisions, but it is not clear to me whether you are allowed to ellide a deleted operation. Pure compiler optimization using the "as if" rule would clearly be forbidden, since the naively equivalent auto y = std::move(x); cannot compile.

Share Improve this question asked Mar 2 at 14:09 Dominik KaszewskiDominik Kaszewski 1,3869 silver badges24 bronze badges 4
  • 3 This depends on language revisions. MSVC defaults to C++14, while recent GCC and Clang default to C++17. – cpplearner Commented Mar 2 at 14:27
  • MSVC accepts when C++17 is set, see demo. – wohlstad Commented Mar 2 at 14:36
  • 1 I use auto p{ std::make_unique<T>(...) }; – Eljay Commented Mar 2 at 15:05
  • @Eljay Nice, that is also an option, did not know this syntax was allowed. – Dominik Kaszewski Commented Mar 2 at 15:58
Add a comment  | 

1 Answer 1

Reset to default 3

Answered in comments by @cpplearner:

Guaranteed copy/move ellision which allows the code to work even if the copy/move is explicitly or implicitly deleted was added in C++17

Issue is not about compilers, but by the their default C++ versions. MSVC -std:c++14 and GCC/clang -std=c++14 all fail to compile, while for c++17 they all work, as expected.

CppReference

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745120725a4612398.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信