首页 > 后端开发 > C++ > 为什么 C 中的'initializer_list”模板类型推导失败?

为什么 C 中的'initializer_list”模板类型推导失败?

Susan Sarandon
发布: 2024-12-05 01:52:09
原创
193 人浏览过

Why Does Template Type Deduction Fail with `initializer_list` in C  ?

initializer_list 和模板类型推导

模板类型推导是 C 的一个强大功能,它允许编译器从传递给模板的参数中推断出模板的类型参数。模板。但是,在某些情况下,编译器无法推导类型参数,并且必须使用所需的类型参数显式实例化模板。

考虑以下函数:

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'});
登录后复制

第一行代码是非法的,因为无法推断模板参数 T。如果显式指定模板参数,它将起作用,例如:

printme<std::vector<char>>({'a', 'b', 'c'})
登录后复制

或:

printme<std::initializer_list<char>>({'a', 'b', 'c'})
登录后复制

其他代码行是合法的,因为参数具有明确定义的类型,因此可以很好地推导模板参数 T。

可能令人困惑的部分是 auto 会选择类型std::initializer_list;但模板参数不会。这是因为 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.
登录后复制

但是,对于 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”模板类型推导失败?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板