Bug 891177 - Add an explanatory comment by the const_cast<> in the Move(const T&) overload. r=luke
authorJeff Walden <jwalden@mit.edu>
Sat, 13 Jul 2013 12:54:18 -0700
changeset 138692 5a4b367aae64db4e6cdaabcf87d4b6c301bb5f3c
parent 138691 269b7a2b7310625157cc4503775fde110096b526
child 138693 31aa18b9b25073aa2a6b82d3f95a54821e81cdb3
push id24964
push userryanvm@gmail.com
push dateTue, 16 Jul 2013 20:04:09 +0000
treeherdermozilla-central@fd10ead17ace [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs891177
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 891177 - Add an explanatory comment by the const_cast<> in the Move(const T&) overload. r=luke
mfbt/Move.h
--- a/mfbt/Move.h
+++ b/mfbt/Move.h
@@ -128,16 +128,30 @@ Move(T& t)
 {
   return MoveRef<T>(t);
 }
 
 template<typename T>
 inline MoveRef<T>
 Move(const T& t)
 {
+  // With some versions of gcc, for a class C, there's an (incorrect) ambiguity
+  // between the C(const C&) constructor and the default C(C&&) C++11 move
+  // constructor, when the constructor is called with a const C& argument.
+  //
+  // This ambiguity manifests with the Move implementation above when Move is
+  // passed const U& for some class U.  Calling Move(const U&) returns a
+  // MoveRef<const U&>, which is then commonly passed to the U constructor,
+  // triggering an implicit conversion to const U&.  gcc doesn't know whether to
+  // call U(const U&) or U(U&&), so it wrongly reports a compile error.
+  //
+  // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50442 has since been fixed, so
+  // this is no longer an issue for up-to-date compilers.  But there's no harm
+  // in keeping it around for older compilers, so we might as well.  See also
+  // bug 686280.
   return MoveRef<T>(const_cast<T&>(t));
 }
 
 /** Swap |t| and |u| using move-construction if possible. */
 template<typename T>
 inline void
 Swap(T& t, T& u)
 {