c++ 为什么CTAD的结果是一个带有迭代器的向量,而不是整数?

qv7cva1a  于 2023-05-02  发布在  其他
关注(0)|答案(1)|浏览(132)
#include <boost/type_index.hpp>
#include <iostream>
#include <vector>

int main()
{
    std::vector<int> initv { 42, 31, 7 };

    std::vector      v1{initv.begin(), initv.end()};  // CTAD
    std::vector<int> v2{initv.begin(), initv.end()};

    std::cout << boost::typeindex::type_id_with_cvr<decltype(v1)>().pretty_name() << std::endl;
    std::cout << boost::typeindex::type_id_with_cvr<decltype(v2)>().pretty_name() << std::endl;
}

输出:

std::vector<__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, std::allocator<__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > > > >
std::vector<int, std::allocator<int> >

CTAD生成一个带有迭代器的向量,而不是整数。
假设std::vector有一个接受迭代器的构造函数,这是正确的吗?

7vhp5slm

7vhp5slm1#

这是因为如何初始化向量。与

std::vector      v1{initv.begin(), initv.end()};

您正在执行 direct-list-initialization,它使用std::initializer_list构造函数,并且列表包含2个std::vector<int>::iterator。这就是为什么它推导迭代器。
如果您切换到使用括号,而不是像

std::vector      v1(initv.begin(), initv.end());

那么你不再使用std::initializer_list构造函数,而是使用迭代器范围构造函数,它将正确地推导出迭代器的value_type
总而言之,当你使用{}时,你是在发出信号,你正在使用一个初始化器列表,所以如果它可用的话,这就是所使用的。
如果您想深入了解C++中的初始化,我强烈建议您观看Nicolai Josuttis CPPCON的演讲“The Nightmare of Initialization in C++”

相关问题