Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><strong>FINAL UPDATE</strong></p> <p>After a very insightful comment by @SebastianRedl I realized that the intention of the standard is to refer to the entire construction of the object, not just the operations inside the constructor. This would mean that there is, indeed, a bug in Visual C++. However, it is still my view that the wording of the standard is not sufficiently clear, so I'll leave the rest of my answer unchanged for posterity.</p> <p>To clarify: The behaviour mentioned by the OP is actually a bug, and in light of this, most of what I say below this update is wrong.</p> <p><strong>End Update</strong></p> <p>This is actually not a compiler bug, but rather a strange quirk of the standard, so your confusion is understandable. </p> <p>According to the C++11 standard, the following is the condition for <code>is_trivially_constructible::value</code> to be <code>true</code>.</p> <p>§20.9</p> <blockquote> <p><code>is_constructible&lt;T,Args...&gt;::value</code> is true and the variable definition for <code>is_constructible</code>, as defined below, is known to call no operation that is not trivial</p> </blockquote> <p>So, <code>is_trivially_constructible</code> is true as long as the given type is constructible with the given arguments and it does not call any non-trivial operations. Your example includes only one such constructor, a copy constructor. In fact, by the definition of "non-trivial operation" (essentially a non-trivial operator or constructor), this does hold for your type. So returning <code>true</code> is correct.</p> <p>However, there is one very strange point! The C+11 standard says the following about copy constructors:</p> <p>§12.8.12 (emphasis mine)</p> <blockquote> <p>A <strong>copy/move constructor</strong> for class X is trivial if it is <strong>not user-provided</strong> and if</p> <ul> <li>class X has no virtual functions (10.3) and no virtual base classes (10.1), and</li> <li>the constructor selected to copy/move each direct base class subobject is trivial, and</li> <li><p>for each non-static data member of X that is of class type (or array thereof), the constructor selected to copy/move that member is trivial;</p> <p>otherwise the copy/move constructor is non-trivial.</p></li> </ul> </blockquote> <p>Since you do provide a user-defined copy constructor your class is not trivially copy constructible. The copy constructor you've given is not trivial. Still, the non-trivial copy constructor <em>does</em> fulfil the necessary criteria for <code>is_trivially_constructible</code> to return <code>true</code> given an argument which matches your copy constructor.</p> <p>In my mind, this seems to be more of a "bug" in the standard. <code>is_trivially_constructible</code> returns whether the type is trivially constructible given certain arguments. This does not seem to guarantee that the constructor itself is deemed trivial!</p> <p><strong>Update:</strong></p> <p>After trying to devise a test to show this following case, I did find a bug in VC11. The logic described by the standard means that, if <code>B</code> is used as a sub-object (member or base) of another type, any constructor of that type which invokes the copy constructor of <code>B</code> should be deemed <strong>non-trivial</strong> by <code>std::is_trivially_constructible</code>. This is not the case in VC11.</p> <p><strong>Example Code</strong></p> <pre><code>#include &lt;iostream&gt; #include &lt;type_traits&gt; struct B { B() {} B(B&amp;) { std::cout &lt;&lt; "not trivial\n"; } }; struct A : B { A(B&amp; B) : b(B){} B b; }; int main() { std::cout &lt;&lt; std::is_trivially_constructible&lt;B, B&amp;&gt;::value &lt;&lt; '\n'; // Should print 1 std::cout &lt;&lt; std::is_trivially_constructible&lt;A, B&amp;&gt;::value &lt;&lt; '\n'; // Should print 0 getchar(); return 0; </code></pre> <p>}</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload