[cfe-dev] Initializer-list overload inconsistency

Nicholas Ormrod via cfe-dev cfe-dev at lists.llvm.org
Thu Dec 10 11:23:10 PST 2015


== Summary ==

In clang 3.7, overload resolution between an initializer-list constructor and a copy constructor favors the copy constructor. The standard seems to specify that explicit initializer-list constructors take precedence in overload resolution. This behavior is different from clang 3.6 and from all versions of gcc. This behavior is not observed when the overload resolution is between an initializer-list constructor and a non-copy constructor.

This was encountered when converting a recursive tree-like type from gcc to clang. The tree-like type could accept an initializer-list of children, but passing a single child would invoke the copy constructor instead.


== Minimal code example: ==

#include <initializer_list>
struct T {
  int x;
  T() : x(0) {}
  T(const T&) : x(1) {}
  T(std::initializer_list<T>) : x(2) {}
};
int foo() {
  T t1;
  T t2 = { t1 };
  return t2.x;
}

In clang 3.7, foo() returns 1. In clang 3.6 and all versions of gcc, foo() returns 2.
The overload resolution in clang 3.7 is consistent with clang 3.6 and gcc when a non-copy constructor is involved; the following example returns 4 on all tested compilers.

#include <initializer_list>
struct T {
  int x;
  T(int) : x(3) {}
  T(std::initializer_list<int>) : x(4) {}
};
int foo() {
  T t = { 7 };
  return t.x;
}


== Standard references (n3936): ==

- 8.5.4 "List-initialization"
- 13.3.1.7, "Initialization by list-initialization"



Regards,
Nicholas
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20151210/7543fe0b/attachment.html>


More information about the cfe-dev mailing list