This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: __rvalref overloads causing ambiguities


Gabriel Dos Reis wrote:

>chris jefferson <caj@cs.york.ac.uk> writes:
>
>| We can't add another level of indirection like you say. I believe we can
>| use some templates to confuse the compiler
>
>and the users and maintainers too. half ;-/
>
>  
>
Hmm.. yes. Anyway, here are my two current plans. They are both based
around the idea that templated constructors / assignment operators don't
take part in this kind of decision (I forget the technical term..). I
had hoped I could poke just the __rvalref class in some way to stop the
compiler thinking it could convert things to it, but that doesn't seem
possible unfortunatly

The first, simpler, one looking one just makes the existing constructors
templated. This means that it might look like you can construct a vector
from any rvalref.. of course the this->swap will refuse to compile
anything other than a vector of the same type (the assignment operator
follows equivalently)

        * @param x A %vector of identical element and allocator types
        *
        * The newly-constructed %vector contains the exact contents of @a x.
-       * The contents of x are a valid, but unspecified vector.
+       * The contents of x are a valid, but unspecified vector. This
+       * constructor is templated to avoid it being used when deducing the
+       * list of types convertable to vector. It will only correctly
compile
+       * when given a vector of identical type to the one being
constructed.
        */
-      vector(__gnu_cxx::__rvalref<vector> __x)
-      : _Base(__x.__ref.get_allocator())
-      {        this->swap(__x.__ref); }
+      template<typename _Type>
+       vector(__gnu_cxx::__rvalref<_Type> __x)
+       : _Base(__x.__ref.get_allocator())
+       {       this->swap(__x.__ref); }


The second option, which in some ways I prefer, but I can imagine other
people won't like..

First add an extra unused template parameter to rvalref with a default
value in moveable.h:

-  template<class _Tp>
+ /**
+  *  This class represents an rvalue reference, which means that if it
+  *  is assigned to another objects, or another object is constructed
from  
+  *  it, then that object may pilfer the internals of __ref.
+  *
+  *  This class has a second, unused template parameter which is templated
+  *  on in some constructores and operator=, so they aren't used for
deducing
+  *  the list of types which can be converted / assigned.
+  */
+  template<class _Tp, class _UnusedType = void>
     struct __rvalref


And then template on it!

        * The newly-constructed %vector contains the exact contents of @a x.
-       * The contents of x are a valid, but unspecified vector.
+       * The contents of x are a valid, but unspecified vector. This
+       * constructor is templated on the unused second template
parameter of
+       * __rvalref to avoid it being used while deducing the list of types
+       * which can be converted to vector.
        */
-      vector(__gnu_cxx::__rvalref<vector> __x)
-      : _Base(__x.__ref.get_allocator())
-      {    this->swap(__x.__ref); }
+      template<typename _UnusedType>
+    vector(__gnu_cxx::__rvalref<vector, _UnusedType> __x)
+    : _Base(__x.__ref.get_allocator())
+    { this->swap(__x.__ref); }

Comments? I'm expecting the first of these to go down better, so unless
anyone comments otherwise, I shall probably finish polishing that, throw
comments everywhere, and add a test or two and come back with a complete
patch.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]