为什么 CTAD 产生带有迭代器的向量,而不是整数?

Too*_*sie 2 c++ vector c++17 ctad

#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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

#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;
}
Run Code Online (Sandbox Code Playgroud)

CTAD 生成带有迭代器的向量,而不是整数。

鉴于std::vector有一个采用迭代器的构造函数,这是正确的吗?

Nat*_*ica 10

这是因为初始化向量的方式不同。和

\n
std::vector      v1{initv.begin(), initv.end()};\n
Run Code Online (Sandbox Code Playgroud)\n

您正在执行直接列表初始化,它使用std::initializer_list构造函数并且列表包含 2 std::vector<int>::iterator。这就是它对迭代器进行推导的原因。

\n

如果您改用括号,例如

\n
std::vector      v1(initv.begin(), initv.end());\n
Run Code Online (Sandbox Code Playgroud)\n

那么您不再使用std::initializer_list构造函数,而是使用迭代器范围构造函数,它将正确推导value_type迭代器的 。

\n
\n

总结一下,当您使用时,{}您表示您正在使用初始化程序列表,因此如果可用,则使用该列表。

\n

如果您想深入了解 C++ 中初始化的兔子洞,我强烈建议您观看 Nicolai Josuttis CPPCON 演讲\xe2\x80\x9cC++ 中初始化的噩梦\xe2\x80\x9d

\n