如果使用 {},函数调用不会产生歧义

Bil*_*ias 6 c++ initialization curly-braces list-initialization c++17

#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;
}
Run Code Online (Sandbox Code Playgroud)

如果第一个函数被注释掉,我会ambiguous call在编译时得到。如果没有注释掉,则调用第一个函数。为什么{}隐式转换为int?

实例:https : //onlinegdb.com/rkhR0NiBD

son*_*yao 5

为什么{}隐式转换为int?

这是复制列表初始化,因为参数值初始化(零初始化)的效果为0int可以从(空)braced-init-list 初始化,就像int i{};or 一样int i = {};

  1. 在函数调用表达式中,使用花括号初始化列表作为参数,列表初始化初始化函数参数

对于f(std::vector<int>)f(std::deque<int>)被调用,一个用户定义的转换(通过的构造std::vectorstd::deque服用std::initializer_list)是必需的; 那么第一个重载在重载决议中获胜。


kam*_*aze 0

编辑:我想删除这篇文章,因为它是错误的(抱歉,我忘记了向量/双端队列的初始化列表构造函数不是模板)。不幸的是,只要它是公认的答案,我就不能这样做。


std::vector和 的单参数构造函数std::deque是显式的。对于空的初始化列表来说,自动类型推导是不可能的,这消除了匹配f(std::vector<int>)f(std::deque<int>)重载的所有方法。

所以构造一个 int 是唯一的匹配。

  • 这是不正确的。`initializer_list` 构造函数不是显式的。事实上,它们都是匹配的,因此存在歧义。 (4认同)