正确编写基于范围的构造函数
Correctly Writing a Range Based Constructor
我有一个关于为类编写基于范围的构造函数的问题,但找不到正确的措辞来搜索谷歌上的帮助。
假设我正在编写一个简单的类,如 vector,它涉及一个基于范围的构造函数,该构造函数将范围内的元素插入到当前容器中:
// foo.h
#ifndef FOO_H
#define FOO_H
#include <iostream>
class Foo {
public:
Foo() {
std::cout << "Default constructor called" << std::endl;
}
template<class InputIterator> Foo(InputIterator first, InputIterator last) {
std::cout << "Range based constructor called" << std::endl;
}
Foo(size_t n, int val) {
std::cout << "size_t, int constructor called" << std::endl;
}
};
#endif // FOO_H
并有一个 CPP 文件
#include <iostream>
#include <vector>
#include "foo.h"
using std::cout; using std::endl;
int main() {
std::vector<int> v(10, 5);
Foo f_default;
Foo f_range(v.begin(), v.end());
Foo f_int(314, 159); // want this to call size_t, int ctctr
return 0;
}
在main的第三行中,我们创建了一个直观地想要调用size_t int构造函数的Foo f_int(314, 159)
。但是,它与范围的通用模板构造函数匹配。有没有办法在C++解决这样的问题?我觉得我错误地处理了基于范围的构造函数。
我可以想象你可以使用模板专业化,但真的不知道如何。
可能发生这种情况的一个例子是,如果我们正在编写一个向量类,其中有一个基于size_t和默认值的构造函数(将在类上模板化,但我在这里进行了简化)和另一个基于迭代器范围的构造函数。
在第三种情况下,构造函数模板是更好的匹配,因为您要传递两个int
参数,而Foo(size_t n, int val)
需要int
才能为第一个参数size_t
转换。如果将代码修改为
Foo f_int(static_cast<size_t>(314), 159);
调用所需的构造函数。但是,当然,这不是一个好的解决方案,因为很容易意外调用错误的构造函数。相反,您可以使用 SFINAE 通过确保参数类型是迭代器,从重载解析集中删除构造函数模板。
template<class InputIterator,
class = std::enable_if_t<
std::is_base_of<
std::input_iterator_tag,
typename std::iterator_traits<InputIterator>::iterator_category
>{}
>
>
Foo(InputIterator first, InputIterator last) {
std::cout << "Range based constructor called" << std::endl;
}
如果您查看此处的表格,您可以从中读取的所有迭代器都是输入迭代器或派生类型。因此,上面的代码正在检查传递给构造函数的InputIterator
类型是否属于该类型或从该类型派生的内容。
相关文章:
- C++11:没有复制构造函数的自定义基于范围的循环
- std::vector 范围构造函数可以调用显式转换吗?
- C++:SFINAE 来区分填充和范围构造函数?
- 如何在C++11中区分填充构造函数和范围构造函数
- 使用范围解析运算符时,在构造函数中调用虚拟方法是否安全?
- 子类化 STL 容器:范围构造函数不起作用
- 基于范围的 std::move 调用意外复制构造函数
- 基于容器范围的构造函数效率
- 删除复制构造函数和运算符=类范围访问
- 正确编写基于范围的构造函数
- 在构造函数中 'cout' 未在此范围内声明
- 为什么范围V3产量需要默认构造函数
- 当第一个 itr 在最后一个 itr 之后时,std::vector 范围构造函数的官方行为是什么?
- C 11矢量构造函数复制与范围
- 无法从构造函数访问私有变量 - 不在范围(C )中
- 比较迭代器value_type范围构造函数
- 如何使用默认移动构造函数将数据移出范围
- C++矢量范围构造函数
- 集合范围构造函数的C++行为
- 如何正确使用向量范围构造函数