Function call not ambiguous if {} is used
Asked Answered
Z

2

6
#include <stdio.h>
#include <vector>
#include <deque>

// 1st function
void f(int i, int j = 10){
    printf("Hello World what");
};

void f(std::vector<int>){
    printf("Hello World vec");
};

void f(std::deque<int>){
    printf("Hello World deq");
};

int main()
{
    f({});
    return 0;
}

If the 1st function is commented out I get ambiguous call when compiling. If not commented out, 1st function is called. Why is {} implicitly converted to int?

Live example: https://onlinegdb.com/rkhR0NiBD

Zingale answered 25/9, 2020 at 9:57 Comment(0)
T
0

Edit: I would like to delete this post because it's false (sorry for that, I forgot that the initialiser list constructor of vector/deque is not a template). Unfortunately I cannot do this as long as it is the accepted answer.


Single argument constructors to std::vector and std::deque are explicit. Automatic type deduction is not possible for an empty initialiser list, that eliminates all ways of matching the f(std::vector<int>) and f(std::deque<int>) overloads.

So constructing an int is the only match.

Throughway answered 25/9, 2020 at 10:14 Comment(1)
This is not correct. The initializer_list constructors are not explicit. In fact, they both match, hence the ambiguity.Tshombe
E
5

Why is {} implicitly converted to int?

This is copy-list-initialization, as the effect the parameter is value-initialized (zero-initialized) as 0. int could be initialized from (empty) braced-init-list, just as int i{}; or int i = {};.

  1. in a function call expression, with braced-init-list used as an argument and list-initialization initializes the function parameter

For f(std::vector<int>) and f(std::deque<int>) to be called, a user-defined conversion (by the constructor of std::vector and std::deque taking std::initializer_list) is required; then the 1st overload wins in overload resolution.

Endomorphic answered 25/9, 2020 at 10:5 Comment(0)
T
0

Edit: I would like to delete this post because it's false (sorry for that, I forgot that the initialiser list constructor of vector/deque is not a template). Unfortunately I cannot do this as long as it is the accepted answer.


Single argument constructors to std::vector and std::deque are explicit. Automatic type deduction is not possible for an empty initialiser list, that eliminates all ways of matching the f(std::vector<int>) and f(std::deque<int>) overloads.

So constructing an int is the only match.

Throughway answered 25/9, 2020 at 10:14 Comment(1)
This is not correct. The initializer_list constructors are not explicit. In fact, they both match, hence the ambiguity.Tshombe

© 2022 - 2024 — McMap. All rights reserved.