0

I'm confused by the cppref statements:

[...] The result of the conversion, which is a prvalue expression (since C++17) if a converting constructor was used, is then used to direct-initialize the object. The last step is usually optimized out and the result of the conversion is constructed directly in the memory allocated for the target object, but the appropriate constructor (move or copy) is required to be accessible even though it's not used. (until C++17)

I tested the code std::atomic_int atom = 1; on gcc 8.0.1, and it compiles with C++17 but fails with C++14 with the following error:

error: use of deleted function 'std::atomic<int>::atomic(const std::atomic<int>&)'
   std::atomic_int atom = 1;
                          ^

Does that mean the appropriate constructor (move or copy) is (always?) no longer required to be accessible in C++17?

Lingxi
  • 14,579
  • 2
  • 37
  • 93

1 Answers1

1

In cases where copy elision is mandatory in C++17, these constructors are never used. In that case there is nothing to check.

In earlier versions, where elision was merely optional, the access checks were required to get consistent result between compilers. Still happens in C++17 for the cases where the elision is not mandatory.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
  • Then to write portable code, one should not assume that constructor accessibility is not checked, right? – Lingxi Feb 17 '18 at 05:02
  • @Lingxi: If you want to be portable with C++14, you have to follow C++14's rules. – Nicol Bolas Feb 17 '18 at 07:31
  • @NicolBolas Let's say I want to be portable with C++17. Still, whether accessibility check is performed depends on whether copy elision is mandatory, which is not specified by the standard. – Lingxi Feb 17 '18 at 08:30
  • @Lingxi: "*Let's say I want to be portable with C++17.*" What does that mean? You're either writing code that compiles in C++14 (which C++17 is backwards compatible with) or code that compiles in C++17 (which C++14 is not necessarily forwards compatible with). – Nicol Bolas Feb 17 '18 at 14:55
  • @Lingxi - Of course the cases where copy elision is mandatory *are* specified in the C++17 standard. I didn't quote anything because I have never ever tried to return an object with a private move constructor, so also haven't bothered to find out *exactly* when it would now work (or not). – Bo Persson Feb 17 '18 at 15:04