如何将大括号括起来的初始化列表传递给函数?

shi*_*jin 3 c++ templates stl list-initialization range-based-loop

我想编写一个可以与参数一起使用的函数,否则该函数可能直接出现在基于范围的循环中:

template <typename Iterable>
void sayIt(const Iterable& stuff) {
    for (const auto& e : stuff) {
        cout << e << endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

这适用于 stl 容器和其他类型,但不适用于大括号封闭的初始化程序:

std::vector<std::string> baz(2, "sorry");
sayIt(baz);              // okay
sayIt({"foo", "bar"});   // not okay
Run Code Online (Sandbox Code Playgroud)

有没有办法让函数同时使用两者?

son*_*yao 6

Braced-init-list 没有类型并导致模板参数推导失败。

非演绎上下文

在以下情况下,用于组成 P 的类型、模板和非类型值不参与模板参数推导,而是使用在其他地方推导或明确指定的模板参数。如果模板参数仅在非推导上下文中使用且未明确指定,则模板参数推导失败。

  1. 参数 P,其 A 是一个花括号初始化列表,但 P 不是std::initializer_list、对一个的引用(可能是 cv 限定的)或对数组的引用:

您可以明确指定模板参数std::initializer_list以绕过推论,

sayIt<std::initializer_list<std::string>>({"foo", "bar"});
Run Code Online (Sandbox Code Playgroud)

或者添加另一个重载 take std::initializer_list

template <typename T>
void sayIt(std::initializer_list<T> stuff) {
    sayIt<decltype(stuff)>(stuff);
}
Run Code Online (Sandbox Code Playgroud)