c++向量构造函数实例化冲突
Posted
技术标签:
【中文标题】c++向量构造函数实例化冲突【英文标题】:c++ vector constructor instantiation conflicts 【发布时间】:2017-05-06 14:35:03 【问题描述】:我正在尝试实现矢量容器引用 http://www.cplusplus.com/reference/vector/vector/vector/。有两个构造函数导致了一些问题:
template <typename T>
vector (size_type n, const T& val);
template <typename T>
template <typename InputIterator>
vector (InputIterator first, InputIterator last);
当我使用vector<int> vec(100, 1);
时。似乎两个模板构造函数都进行了实例化。所以我得到了带有 T=int 的 template <typename T> vector (size_type n, const T& val)
和带有 T=int, InputIterator=int 的 template <typename T> template <typename InputIterator> vector (InputIterator first, InputIterator last)
。
我该如何解决?
【问题讨论】:
“两个模板构造函数都进行实例化”是什么意思? 另外你怎么看有冲突?你得到什么错误信息?提供minimal reproducible example 【参考方案1】:请注意,标准(自 C++11 起)要求以迭代器为参数的重载 constructor of std::vector
仅在传递的参数充当迭代器时才参与重载决策。
此重载仅在 InputIt 满足 InputIterator 时才参与重载解析,以避免与重载 (2) 产生歧义。
您可以使用SFINAE 和std::iterator_traits 来完成您自己的向量实现。例如
template <typename InputIterator, typename = typename std::iterator_traits<InputIterator>::value_type>
vector (InputIterator first, InputIterator last) ...
对于InputIterator = int
的情况,std::iterator_traits<int>
不包含value_type
之类的任何成员类型,则重载将被排除在重载解析之外。
顺便说一句:更准确地说,问题不在于“两个模板构造函数都进行实例化”;我不确定您的实现中size_type
的确切类型是什么,如果它是int
以外的其他类型,例如std::size_t
,那么对于vector<int> vec(100, 1);
,将不会选择第一个重载,因为它需要转换从int
到std::size_t
的第一个参数,然后将选择第二个重载,因为它可以产生与InputIterator = int
的完美匹配实例化。这不是我们所期望的行为。
【讨论】:
以上是关于c++向量构造函数实例化冲突的主要内容,如果未能解决你的问题,请参考以下文章
使用在同一命名空间中定义的构造函数实例化命名空间中的对象。 C++