简体   繁体   中英

Why are these arguments ambiguous for a class constructor overload but not ambiguous for a function overload?

The issue is easily resolved by not being an implicit conversion fiend, but it seems like a strange inconsistency to me. Here's an example:

#include <unordered_set>

void test1(int a, int b); // Overloaded function with two different
void test1(std::unordered_set<char> set); // possible argument types

struct Test2 {
  Test2(int a, int b); // Overloaded constructor with two different
  Test2(std::unordered_set<char> set); // possible argument types
};

int main() {

  test1(123,456); // Testing out the overloaded functions
  test1({'a','b'}); // This works correctly with no ambiguity complaint
  // Neither GCC nor CLang mistake the initializer list of
  // two chars as possibly being two ints instead.

  Test2(123,456); // Testing out the overloaded constructors
  Test2({'a','b'}); // Error: more than one instance of constructor 
                  // "Test::Test" matches the argument list:C/C++(309)
}

// GCC & Clang complain about ambiguity for the implicit conversion in the constructor overload
// GCC gives error: call of overloaded ‘Test2(<brace-enclosed initializer list>)’ is ambiguous
// CLang gives error: call to constructor of 'Test2' is ambiguous

I know that using explicit Test2(int a, int b); resolves the issue in CLang, whereas GCC still gives the same complaint.

Why would two compilers that can deduce the correct types of arguments for overloaded functions refuse to do the same thing for overloaded constructors?

This is a fun one. {'a', 'b'} could be a request to use Test2(int a, int b) to construct a temporary Test2 that can then be used to copy or move construct another Test2 . Eg:

Test2 b = {'a', 'b'};

This won't happen with

Test2({'a'});

or

Test2({'a','b','c'});

because they don't match another constructor.

The Quick Solution is to use braces instead of brackets

Test2{{'a','b'}};

but I have yet to find a definitive Standard quote on why this is.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM