c++ - 编译器如何区分 std::vector 的构造函数?

标签 c++ templates vector constructor

std::vector<T>类有以下两个构造函数:

vector(size_type count, const T& value, const Allocator& alloc = Allocator());
template <class InputIt>
vector(InputIt first, InputIt last, const Allocator& alloc = Allocator());

当用 T=size_t 实例化时,这些似乎能够发生冲突(与 InputIt=size_t ),但它不会发生。为什么?

为了清楚起见,这里有一个最小的代码示例:

#include <iostream>

template <typename T>
struct A {
  A(size_t n, const T &v) { std::cout << n << " x " << v << std::endl; }
  template <typename I>
  A(I first, I last) { std::cout << first << " ... " << last << std::endl; }
};

int main() {
  size_t x = 3, y = 42;
  A<size_t> a1(x, y);    // prints 3 x 42
  A<size_t> a2(3, 42);   // prints 3 ... 42
}

编辑:我也将 @jrok 的版本放在示例中。为什么 a1 中的构造函数之一被优先考虑,另一个在 a2 中?

最佳答案

在重载解析期间,编译器需要在 InputIt 时从候选函数集中删除模板重载。不会被推导为迭代器类型(更正式地说,当它不满足 LegacyInputIterator 概念时 - 请参阅 this page 上的注释 (5))。

删除用户代码中的重载是通过 SFINAE 完成的技术,尽管编译器实现可以使用其他东西 - 它们并不严格要求使用合法的 C++ 代码。例如,我的(MinGW)编译器使用 SFINAE 实现它:

template<typename _InputIterator,
           typename = std::_RequireInputIter<_InputIterator>>
    vector(_InputIterator __first, _InputIterator __last,
       const allocator_type& __a = allocator_type());

哪里_RequireInputIter

 template<typename _InIter>
    using _RequireInputIter = typename
      enable_if<is_convertible<typename
        iterator_traits<_InIter>::iterator_category,
                   input_iterator_tag>::value>::type;

此要求在 C++11 中生效,因此在此之前,您实际上可能会调用错误的构造函数。如果我们稍微修改一下您的示例:

#include <iostream>

template <typename T>
struct A {
  A(size_t n, const T &v) { std::cout << n << " x " << v << std::endl; }
  template <typename I>
  A(I first, I last) { std::cout << first << " ... " << last << std::endl; }
};

int main() {
  A<size_t> a(3, 42);
}

现在打印 3 ... 42 .

关于c++ - 编译器如何区分 std::vector 的构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60339723/

相关文章:

c++ - 我的 vector 迭代器出现了一个奇怪的错误

c++ - QTableView/QTableWidget 缓存不同的 View

c++ - 如何使用 boost 预处理器生成访问器?

c++ - 可变参数模板(带有类和函数)编译失败

C++ 无效数组<T, N> 下标

c++ - `type` 对于 std::vector 而不是 OpenCV 中的 cv::Mat 的解释是什么?我该如何更改它? (C++)

c++ - 如何打印类型 vector<pair<char, int>> 来筛选 c++?

c++ - 有符号/无符号比较

c++ - 程序在 cin 之后停止 - C++

C++ void_t SFINAE false_type true_type 无法获得特化