Ver*_*tas 6 c++ templates c++11 list-initialization type-deduction
我有关于函数模板参数类型推导过程的问题.
举个例子:
#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;
}
Run Code Online (Sandbox Code Playgroud)
如果我理解正确,第二个参数推断为std::istream_iterator默认构造函数的类型.
适当的std::vector构造函数声明为:
template <class InputIterator>
vector (InputIterator first, InputIterator last,
const allocator_type& alloc = allocator_type());
Run Code Online (Sandbox Code Playgroud)
由于推导出第一个参数类型,因为std::istream_iterator<int>第二个参数也被推导出来std::istream_iterator<int>,因此可以应用统一初始化语义.我不知道的是类型推导发生的顺序.我真的很感激这方面的一些信息.
提前致谢!
让我们使用一个更简单的例子:
template<class T>
void foo(T, T);
foo(42, {});
Run Code Online (Sandbox Code Playgroud)
函数调用有两个参数:
int(整数文字){}后者{}可以是表达式列表的一部分,但它本身不是表达式.一个表达式列表被定义为初始列表.braced-init-lists没有类型.
模板类型推导分别针对每个函数参数[temp.deduct.type]/2进行.[temp.deduct.call]/1表示关于函数参数的类型推导P:
如果从某些P'中删除引用和cv限定符
P给出std::initializer_list<P'并且参数是初始化列表,则对初始化列表的每个元素执行推导,将P'作为函数模板参数类型并将初始化元素作为它的论点.否则,初始化列表参数会将参数视为非推导的上下文.[强调我的]>
因此在调用foo(42, {});中T不会从第二个参数中推断出{}.但是,T可以从第一个参数推断出来.
通常,我们可以T从多个函数参数中推断出来.在这种情况下,推导出的类型必须与[temp.deduct.type]/2完全匹配.如果类型仅从一个函数参数推导出来但在别处使用(在非推导上下文中的另一个函数参数中,在返回类型中等),则没有问题.类型推导可能会失败,例如,当模板参数无法从任何函数参数推导出来且未明确设置时.
扣除后,T将被替换int,产生类似于的函数签名:
void foo<int>(int, int);
Run Code Online (Sandbox Code Playgroud)
这个功能可以用两个参数来调用42和{}.后者将执行复制列表初始化,从而导致第二个参数的值初始化.
| 归档时间: |
|
| 查看次数: |
324 次 |
| 最近记录: |