home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c++.moderated      Moderated discussion of C++ superhackery      33,346 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 31,693 of 33,346   
   =?ISO-8859-1?Q?Daniel_Kr=FCgler?= to All   
   Re: How to conditionally disable a copy    
   24 Nov 11 23:24:48   
   
   f8f65894   
   From: daniel.kruegler@googlemail.com   
      
   Am 24.11.2011 21:41, schrieb SG:   
   > On 23 Nov., 23:40, Daniel Krügler wrote:   
   >> On 2011-11-23 17:07, SG wrote:   
   >>   
   >>> I wonder how std::vector is supposed to handle this. As far as I know,   
   >>> you are allowed to define members which cannot be instantiated as long   
   >>> as you don't try to instantiate them.   
   >>   
   >> Yes for the second part. Does this answer your first question? Otherwise   
   >> I'm not sure what you exactly mean in regard to std::vector.   
   >   
   > The problem I see with conditionally supporting copy construction with   
   > a class template like std::vector is that you *could* just implement   
   > the copy ctor and rely on people not using it for move-only types. No   
   > instantiation = no errors. But what is   
   > std::is_copy_constructible::value supposed to evaluate to in case   
   > MOC is a container of move-only elements (like a vector of   
   > unique_ptrs)?   
      
   Well, the standard does not *require* that this works. This is QoI.   
      
   > In an ideal world it would return false. But   
   > is_copy_constructible  is defined in terms of   
   > is_constructible. Checking one of the latest C++ ISO   
   > standard drafts I found the following part:   
   >   
   >    "...the predicate condition of is_constructible  shall   
   >     be satisfied  if and only if  the following variable definition   
   >     would be well-formed for some invented variable t:   
   >   
   >       T t (create()...);   
   >   
   >     Access checking is performed  as if in a context unrelated to T   
   >     and any of the Args. Only the validity of the immediate context   
   >     of  the  variable  initialization  is  considered.  [ Note: The   
   >     evaluation of  the initialization  can result  in side  effects   
   >     such as  instantiation of  class template  specializations  and   
   >     function template specializations, the generation of implicitly-   
   >     defined functions, and so on.  Such side effects are not in the   
   >     'immediate context'  and can result in  the program  being ill-   
   >     formed. -- end note ]"   
   >   
   > So, it seems like library implementers have to go a couple of extra   
   > miles to make is_copy_constructible>>::value   
   > evaluate to false instead of failing to compile.   
      
   Note that library implementations can add (conditional)   
   noexcept-specifications in addition to what the standard library   
   requires, see [res.on.exception.handling] p1.   
      
   But we have to consider that C++11 has just been published, so the   
   library group was a bit conservative with required specifications. We   
   may need more in the future.   
      
   Arguably, this becomes complicated when taking the new allocator model   
   into account, because actually we don't have to consider   
   std::is_constructible, but we would need a new trait   
   std::is_copy_insertable and is_move_insertable. There is no reason why   
   implementations should not experiment with such internal traits.   
      
   My assumption is, that user experience in the following years might   
   impose enough pressure on implementations to provide better compile-time   
   support here, which again is the usual seed for standardization.   
      
   > Side note: We don't need create<>  anymore since we got declval<>,   
   > right?   
      
   We really do need create() here, because we have the following problem:   
      
   is_constructible is defined as a variable definition and there does not   
   exist (to my knowledge) a simple transformation of such a beast into a   
   single, equivalent expression (It is possible to define a rather   
   complicated series of expressions that have the same effect, though).   
   Now, given expressions, we can easily talk about an unevaluated operand,   
   but we have no pendant for this for variable definitions. *If* we would   
   allow lambda expressions in unevaluated contexts, this would have been a   
   nice tool for this by simply writing something along the lines of:   
      
   decltype([]{ T t(std::declval()...); })   
      
   But such unevaluated lambda expressions would cause a lot of   
   specification problems, mostly in regard to equivalence of declarations   
   of functions or function templates, where the signature is defined in   
   terms of such expressions, so I believe there is a far route to go,   
   until finally lambda expressions would be allowed in unevaluated   
   expressions.   
      
   Given these limitations, it is not possible to specify   
   std::is_constructible in terms of std::declval, because this entity   
   would be considered as odr-used within the definition. This again would   
   make the variable definition ill-formed in (basically) every case. Since   
   this trait is defined in terms of well-formed code, the effect would be   
   that std::is_constructible would return false for nearly all   
   initialization cases ;-)   
      
   Summarizing, using create here is just a technical trick to solve a   
   subtle specification problem.   
      
   >>> IMHO, C++ desperately needs a "requires" that's not only a native   
   >>> enable_if replacement but can also enable/disable non-template members   
   >>> of class templates. I'd even be happy about a requires-clause which   
   >>> only takes a compile-time boolean and does not involve "modular type   
   >>> checking".   
   >>   
   >> In current C++11 this is possible for all members except for the special   
   >> members thanks to default template parameters.   
   >   
   > I guess you mean ... by turning them into member templates +   
   > exploiting SFINAE.   
      
   Yes, exactly, this is what I meant.   
      
   HTH & Greetings from Bremen,   
      
   Daniel Krügler   
      
      
   --   
         [ See http://www.gotw.ca/resources/clcm.htm for info about ]   
         [ comp.lang.c++.moderated.    First time posters: Do this! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca