c++ - initializer_list 和模板类型推导

标签 c++ templates c++11 initializer-list

考虑函数:

template<typename T>
void printme(T&& t) {
  for (auto i : t)
    std::cout << i;
}

或任何其他需要一个带有 begin()/end() 参数的函数 - 启用类型。

为什么以下是非法的?

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

当所有这些都合法时:

printme(std::vector<char>({'a', 'b', 'c'}));
printme(std::string("abc"));
printme(std::array<char, 3> {'a', 'b', 'c'});

我们甚至可以这样写:

const auto il = {'a', 'b', 'c'};
printme(il);

printme<std::initializer_list<char>>({'a', 'b', 'c'});

最佳答案

您的第一行 printme({'a', 'b', 'c'})是非法的,因为模板参数 T无法推断。如果您明确指定模板参数,它将起作用,例如printme<vector<char>>({'a', 'b', 'c'})printme<initializer_list<char>>({'a', 'b', 'c'}) .

您列出的其他是合法的,因为参数具有明确定义的类型,因此模板参数 T可以推导出来就好了。

您的 auto 的片段也有效,因为 il被认为是 std::initializer_list<char> 类型, 因此 printme() 的模板参数可以推导出来。


这里唯一“有趣”的部分是 auto将选择类型 std::initializer_list<char>但模板参数不会。这是因为 C++11 标准的 § 14.8.2.5/5 明确指出这是模板参数的非推导上下文:

A function parameter for which the associated argument is an initializer list (8.5.4) but the parameter does not have std::initializer_list or reference to possibly cv-qualified std::initializer_list type. [Example:

template<class T> void g(T);
g({1,2,3}); // error: no argument deduced for T

— end example ]

但是对于 auto , § 7.1.6.4/6 明确支持 std::initializer_list<>

if the initializer is a braced-init-list (8.5.4), with std::initializer_list<U>.

关于c++ - initializer_list 和模板类型推导,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12431495/

相关文章:

c++ - 调整大小时数组 "breaks"

c++ - gcc 和 clang 上奇怪的嵌套类部分特化结果

c++ - const_forward 在 C++ 的可选实现中做了什么?

c++ - 通过另一个 C++ 函数更改函数变量

javascript - 获取 youtube 视频的签名

templates - 在Grails域类中定义表头以生成 View

c++ - 在奇怪的重复模板类中使用方法的返回类型作为另一个方法的参数类型

c++ - 在 C++11 中高效地复制 vector ?

c++ - 为子类使用父类构造函数

c++ - std::chrono 纳秒计时器适用于 MSVC,但不适用于 GCC