gpt4 book ai didi

c++ - Braced-init-lists 和函数模板类型推导顺序

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:21:28 26 4
gpt4 key购买 nike

我有一个关于函数模板参数类型推导过程的问题。

举个例子:

#include <vector>
#include <sstream>
#include <string>
#include <iterator>
#include <fstream>

int main()
{
std::ifstream file("path/to/file");
std::vector<int> vec(std::istream_iterator<int>{file},{}); // <- This part
return 0;
}

如果我理解正确,第二个参数被推断为 std::istream_iterator 类型其中调用了默认构造函数。

适当std::vector构造函数声明为:

template <class InputIterator>
vector (InputIterator first, InputIterator last,
const allocator_type& alloc = allocator_type());

因为第一个参数类型推导为std::istream_iterator<int>第二个参数推导为std::istream_iterator<int>也因此可以应用统一的初始化语义。我不知道的是类型推导发生的顺序。如果能提供一些相关信息,我将不胜感激。

提前致谢!

最佳答案

让我们用一个更简单的例子:

template<class T>
void foo(T, T);

foo(42, {});

函数调用有两个参数:

  • int 类型的纯右值表达式(整数文字)
  • braced-init-list {}

后者,{} , 可以是表达式列表的一部分,但它本身不是表达式表达式列表 定义为初始化列表braced-init-lists 没有类型。

模板类型推导是针对每个函数参数单独完成的 [temp.deduct.type]/2。 [temp.deduct.call]/1 说明函数参数的类型推导 P :

If removing references and cv-qualifiers from P gives std::initializer_list<P'> for some P' and the argument is an initializer list, then deduction is performed instead for each element of the initializer list, taking P' as a function template parameter type and the initializer element as its argument. Otherwise, an initializer list argument causes the parameter to be considered a non-deduced context. [emphasis mine]

所以在调用foo(42, {}); T不会从第二个参数推导出{} .然而,T可以从第一个参数推导出来。

一般来说,我们可以推导出T来自多个函数参数。在这种情况下,推导的类型必须完全匹配 [temp.deduct.type]/2。如果类型仅从一个函数参数推导出来但在其他地方使用(在非推导上下文中的另一个函数参数中,在返回类型中等),则没有问题。类型推导可能会失败,例如当无法从任何函数参数推导出模板参数并且未明确设置时。

扣除后,T将被 int 取代,生成类似于以下的函数签名:

void foo<int>(int, int);

这个函数可以用两个参数调用 42{} .后者将执行复制列表初始化,从而导致第二个参数的值初始化。

关于c++ - Braced-init-lists 和函数模板类型推导顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24059738/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com