[llvm-bugs] [Bug 39580] New: Overload resolution failure with multi-element initializer_list

via llvm-bugs llvm-bugs at lists.llvm.org
Wed Nov 7 07:03:54 PST 2018


            Bug ID: 39580
           Summary: Overload resolution failure with multi-element
           Product: clang
           Version: 7.0
          Hardware: PC
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: C++
          Assignee: unassignedclangbugs at nondot.org
          Reporter: idart at hotmail.com
                CC: dgregor at apple.com, llvm-bugs at lists.llvm.org,
                    richard-llvm at metafoo.co.uk

Test case:

#include <iostream>
#include <string>
#include <vector>

namespace {

struct Attribute
    explicit Attribute(std::string name, std::string value)
        : name(name), value(value) {}
    std::string name;
    std::string value;

struct Print
    void print(const std::string& s)
    { std::cout << "[String] " << s << std::endl; }

    void print(const std::vector<Attribute>& v)
    { std::cout << "[Vector] " << v[0].name << std::endl; }


int main()
    const Attribute foo("foo", "True");
    const Attribute bar("bar", "True");

    Print p;
    p.print( {foo} );
    p.print( {foo, bar} );

    return 0;

Compiling this with Clang 7 (or 6 for that matter), using "-std=c++17
-stdlib=libc++" produces:

error: call to member function 'print' is ambiguous
    p.print( { foo, bar } );

note: candidate function
    void print(const std::string& s)

note: candidate function
    void print(const std::vector<Attribute>& v)

I am not sure whether this is a Clang bug or a libc++ bug. Switching to
libstdc++ makes it compile and run just fine. And you get the same error using
g++ with libc++ as well, so it's at least in some ways related to the library

AFAIU, the call with the single-element initializer_list could hit
std::string's copy constructor (which might make this related to bug 23812) and
therefore discard that overload. That would leave std::vector's
initializer_list constructor as the only viable option (I believe), and
therefore it works.

But the failing multi-element initializer_list call... It's not telling me
which std::string constructor it is considering, so I find it hard to speculate
further what's going on there.

There's several ways to work around the problem. Using double braces works,
presumably as that reduces it to a single-element initializer_list again. Going
via a initializer_list variable also works; auto li = { foo, bar }; t.test(li);

You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20181107/a1e575d3/attachment.html>

More information about the llvm-bugs mailing list