为什么variadic函数不能"吃掉"C++ 11中的list-initialization参数?

aby*_*s.7 14 c++ variadic-functions compiler-bug c++11 list-initialization

示例代码是:

#include <unordered_map>

int main() {
    std::unordered_map<int, std::pair<int, int>> map;

    map.emplace(1, {1, 1});

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

哪里emplace()有签名,如:

template <class... _Args>
pair<iterator, bool> emplace(_Args&&... __args);
Run Code Online (Sandbox Code Playgroud)

gcc说的功能expectes 0参数- 2提供的.该clang说,函数需要1个参数- 2提供的.

我甚至不明白 - 这段代码有什么问题?

Pup*_*ppy 12

问题是它{1, 1}不是表达式而且没有类型.由于它没有类型,因此无法推断到模板参数列表中.它们都不正确,因为问题与提供的参数数量无关.


Ali*_*Ali 7

我甚至不明白 - 这段代码有什么问题?

出于某些不明原因,initializer-list参数是一个非推导的上下文,请参阅initializer_list和模板类型推导.这是因为C++ 11标准的§14.8.2.5/ 5这样说.我不知道这种看似不一致和违反直觉的行为的理由,但我们并不孤单:

至于你的情况,也许最简单的解决方法是:

map.emplace(1, std::make_pair(1, 1));
Run Code Online (Sandbox Code Playgroud)

  • @Xeo我不明白你的榜样.`auto x = {1,"hi"};`也是一个编译时错误,所以你要做的是什么? (2认同)
  • @Xeo我想改变它已经太晚了,这会打破很多代码.但是,您是否看到任何一个案例,其中推断函数模板参数的`initializer_list`可能会适得其反? (2认同)