【发布时间】:2021-09-13 03:09:19
【问题描述】:
我怀疑这个webpage中给出的std::vector(以及许多其他STL类型)的填充构造函数和范围构造函数的原型是不正确的,所以我实现了一个NaiveVector来模仿这两个原型。
我的代码是:
#include <iostream>
#include <vector>
using namespace std;
template <typename T>
struct NaiveVector {
vector<T> v;
NaiveVector(size_t num, const T &val) : v(num, val) { // fill
cout << "(int num, const T &val)" << endl;
}
template <typename InputIterator>
NaiveVector(InputIterator first, InputIterator last) : v(first, last) { // range
cout << "(InputIterator first, InputIterator last)" << endl;
}
size_t size() const { return v.size(); }
};
int main() {
NaiveVector<int> myVec1(5,1); // A
cout << "size = " << myVec1.size() << endl;
for (auto n : myVec1.v) { cout << n << " "; }
cout << endl;
cout << "-----" << endl;
vector<int> vec({1,2,3,4,5});
NaiveVector<int> myVec2(vec.begin(), vec.end());// B
cout << "size = " << myVec2.size() << endl;
for (auto n : myVec2.v) { cout << n << " "; }
cout << endl;
}
输出是:
$ g++ overload.cc -o overload -std=c++11
$ ./overload
(InputIterator first, InputIterator last) // should be: (int num, const T &val)
size = 5
1 1 1 1 1
-----
(InputIterator first, InputIterator last)
size = 5
1 2 3 4 5
正如我从一开始就怀疑的那样,编译器无法正确区分这两个构造函数。那么我的问题是:std::vector的填充构造函数和范围构造函数如何区分?
改写:如何实现这个NaiveVector的两个构造函数?
这个问题似乎与this 问题重复,但答案并不令人满意。此外,C++11 本身不提供
is_iterator<>..(MSVC 有很多 hack)。
编辑:允许将右值绑定到常量左值引用,因此NaiveVector 的第一个构造函数对A 有效。
【问题讨论】:
-
“我怀疑这个网页中给出的 std::vector (以及许多其他 STL 类型)的填充构造函数和范围构造函数的原型不正确,” - 好吧,这不会让我感到惊讶,但为什么不简单地使用标准库中的正确原型呢?
-
InputIterator仅表示模板参数名称。与std::vector<T>::iterator无关。 -
@user0042 你是对的,但我并不是说
InputIterator应该是std::vector<T>::iterator。它确实可以是任何满足input iterator 要求的类。 -
cplusplus.com 是垃圾。 cppreference.com 的更好参考。特别注意:“此重载仅在
InputIt满足InputIterator时才参与重载解决,以避免与重载 (2) 产生歧义。”这通常通过SFINAE 实现
标签: c++ c++11 constructor overloading