- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是 C++ 的新手,作为学习练习,我正在创建自己的简单 vector 类。
它似乎工作得很好,除了当我创建一个 Vec 对象试图使用
Vec(size_type n, const T& val = T()) 构造函数,它反而想使用应该采用两个迭代器/指针的模板化构造函数,并给我错误。
我相信我理解为什么会发生这种情况,但我想不出一种方法可以在不改变类的使用方式的情况下减少歧义。我想保持与 std::vector 相同的用法。
如何调用正确的构造函数? std::vector 如何避免这个问题?
Vec.h
//#includes: <algorithm> <cstddef> <memory>
template <class T> class Vec
{
public:
//typedefs for iterator, size_type....
//just used T* for iterator
Vec() { create(); }
Vec(const Vec& v) { create(v.begin(), v.end()); }
explicit Vec(size_type n, const T& val = T()) { create(n, val); }
template <class InputIt>
Vec(InputIt first, InputIt last) { create(first, last); }
~Vec() { uncreate(); }
T& operator[](size_type i) { return data[i]; }
const T& operator[](size_type i) const { return data[i]; }
Vec& operator=(const Vec&);
//functions such as begin(), size(), etc...
private:
iterator data;
iterator avail;
iterator limit;
std::allocator<T> alloc;
void create();
void create(size_type, const T&);
template <class InputIt>
void create(InputIt first, InputIt last)
{
data = alloc.allocate(last - first);
limit = avail = std::uninitialized_copy(first, last, data);
}
void uncreate();
void grow();
void unchecked_append(const T&);
};
template <class T>
Vec<T>& Vec<T>::operator=(const Vec& rhs)
{
if (&rhs != this)
{
uncreate();
create(rhs.begin(), rhs.end());
}
return *this;
}
template <class T> void Vec<T>::create()
{
data = avail = limit = 0;
}
template <class T> void Vec<T>::create(size_type n, const T& val)
{
data = alloc.allocate(n);
limit = avail = data + n;
std::uninitialized_fill(data, limit, val);
}
template <class T>
void Vec<T>::create(const_iterator i, const_iterator j)
{
data = alloc.allocate(j - i);
limit = avail = std::uninitialized_copy(i, j, data);
}
template <class T> void Vec<T>::uncreate()
{
if (data)
{
iterator it = avail;
while (it != data)
alloc.destroy(--it);
alloc.deallocate(data, limit - data);
}
data = limit = avail = 0;
}
//left out what I didn't think was relevant
除了我上面提到的情况,它似乎工作正常。
main.cpp
#include "Vec.h"
main()
{
Vec<int> v1(10, 100);
}
我收到错误:
||=== Build: Debug in Vec Class (compiler: GNU GCC Compiler) ===|c:\program files\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\stl_uninitialized.h||In instantiation of '_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = int; _ForwardIterator = int*]':|F:\CBProjects\Accelerated C++\Programming with Classes\Vec Class\Vec.h|58|required from 'void Vec::create(InputIt, InputIt) [with InputIt = int; T = int]'|F:\CBProjects\Accelerated C++\Programming with Classes\Vec Class\Vec.h|24|required from 'Vec::Vec(InputIt, InputIt) [with InputIt = int; T = int]'|F:\CBProjects\Accelerated C++\Programming with Classes\Vec Class\main.cpp|9|required from here|c:\program files\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\stl_uninitialized.h|113|error: no type named 'value_type' in 'struct std::iterator_traits'|||=== Build failed: 1 error(s), 4 warning(s) (0 minute(s), 0 second(s)) ===|
This is my first time asking a question on here. I hope I asked properly and provided enough information. Please let me know if I made a mistake in this process, and thank you for any help you can provide.
For anyone wondering what I ended up doing. I changed the templated constructor so that it won't be invoked with arithmetic arguments(since it's only meant for iterators/pointers).
template <class InputIt>
Vec(InputIt first, InputIt last,
typename std::enable_if<!std::is_arithmetic<InputIt>::value>::type* = 0) {create(first, last); }
它似乎工作正常,但实际上我对 enable_if 不是很熟悉,所以如果有人知道这种方法有任何危险,请告诉我。
最佳答案
选择模板构造函数是因为它更适合参数。
查看 vector constructor 的文档您会看到一条注释,指出如果参数满足 InputIterator
的要求,则此构造函数仅参与重载决策。这通常是通过使用 SFINAE 禁用过载来实现的。 .以下是 libcpp 是如何实现的。我试图删除一些不必要的部分并调整命名约定以提高可读性。
在实际实现中,此构造函数的通常定义如下所示:
template <class InputIterator>
vector(InputIterator first, InputIterator last,
typename enable_if<is_input_iterator <InputIterator>::value>::type* = 0);
template <class InputIterator>
vector(InputIterator first, InputIterator last, const allocator_type& a,
typename enable_if<is_input_iterator <InputIterator>::value>::type* = 0);
我删除了进一步区分 InputIterator
和 ForwardIterator
的不必要部分。 SFINAE is the enable_if的重要部分及其参数。
下面是is_input_iterator
的必要定义:
template <class Tp, class Up,
bool = has_iterator_category<iterator_traits<Tp> >::value>
struct has_iterator_category_convertible_to
// either integral_constant<bool, false> or integral_constant<bool, true>
: public integral_constant<
bool,
is_convertible<typename iterator_traits<Tp>::iterator_category, Up>::value
>
{};
// specialization for has_iterator_category<iterator_traits<Tp> >::value == false
template <class Tp, class Up>
struct has_iterator_category_convertible_to<Tp, Up, false> : public false_type {};
template <class Tp>
struct is_input_iterator
: public has_iterator_category_convertible_to<Tp, input_iterator_tag> {};
它的本质是检查给定类型是否具有可以转换为input_iterator_tag
的iterator_category
标签。
has_iterator_category
就更晦涩了:
template <class Tp>
struct has_iterator_category
{
private:
struct two {char lx; char lxx;};
template <class Up> static two test(...);
template <class Up> static char test(typename Up::iterator_category* = 0);
public:
static const bool value = sizeof(test<Tp>(0)) == 1;
};
它用于检查给定类型是否具有名为 iterator_category
的成员。如果答案是no
,has_iterator_category_convertible_to
将简单地默认为false_type
。如果不这样做,将访问不存在的名称并触发硬编译器错误,这不是您想要在 SFINAE 中执行的操作。
关于c++ - 在自定义 vector 类中调用了错误的构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24346869/
好的,所以我编辑了以下... 只需将以下内容放入我的 custom.css #rt-utility .rt-block {CODE HERE} 但是当我尝试改变... 与 #rt-sideslid
在表格 View 中,我有一个自定义单元格(在界面生成器中高度为 500)。在该单元格中,我有一个 Collection View ,我按 (10,10,10,10) 固定到边缘。但是在 tablev
对于我的无能,我很抱歉,但总的来说,我对 Cocoa、Swift 和面向对象编程还很陌生。我的主要来源是《Cocoa Programming for OS X》(第 5 版),以及 Apple 的充满
我正在使用 meta-tegra 为我的 NVIDIA Jetson Nano 构建自定义图像。我需要 PyTorch,但没有它的配方。我在设备上构建了 PyTorch,并将其打包到设备上的轮子中。现
在 jquery 中使用 $.POST 和 $.GET 时,有没有办法将自定义变量添加到 URL 并发送它们?我尝试了以下方法: $.ajax({type:"POST", url:"file.php?
Traefik 已经默认实现了很多中间件,可以满足大部分我们日常的需求,但是在实际工作中,用户仍然还是有自定义中间件的需求,为解决这个问题,官方推出了一个 Traefik Pilot[1] 的功
我想让我的 CustomTextInputLayout 将 Widget.MaterialComponents.TextInputLayout.OutlinedBox 作为默认样式,无需在 XML 中
我在 ~/.emacs 中有以下自定义函数: (defun xi-rgrep (term) (grep-compute-defaults) (interactive "sSearch Te
我有下表: 考虑到每个月的权重,我的目标是在 5 个月内分散 10,000 个单位。与 10,000 相邻的行是我最好的尝试(我在这上面花了几个小时)。黄色是我所追求的。 我试图用来计算的逻辑如下:计
我的表单中有一个字段,它是文件类型。当用户点击保存图标时,我想自然地将文件上传到服务器并将文件名保存在数据库中。我尝试通过回显文件名来测试它,但它似乎不起作用。另外,如何将文件名添加到数据库中?是在模
我有一个 python 脚本来发送电子邮件,它工作得很好,但问题是当我检查我的电子邮件收件箱时。 我希望该用户名是自定义用户名,而不是整个电子邮件地址。 最佳答案 发件人地址应该使用的格式是: You
我想减小 ggcorrplot 中标记的大小,并减少文本和绘图之间的空间。 library(ggcorrplot) data(mtcars) corr <- round(cor(mtcars), 1)
GTK+ noob 问题在这里: 是否可以自定义 GtkFileChooserButton 或 GtkFileChooserDialog 以删除“位置”部分(左侧)和顶部的“位置”输入框? 我实际上要
我正在尝试在主页上使用 ajax 在 magento 中使用 ajax 显示流行的产品列表,我可以为 5 或“N”个产品执行此操作,但我想要的是将分页工具栏与结果集一起添加. 这是我添加的以显示流行产
我正在尝试使用 PasswordResetForm 内置函数。 由于我想要自定义表单字段,因此我编写了自己的表单: class FpasswordForm(PasswordResetForm):
据我了解,新的 Angular 7 提供了拖放功能。我搜索了有关 DnD 的 Tree 组件,但没有找到与树相关的内容。 我在 Stackblitz 上找到的一个工作示例.对比drag'ndrop功能
我必须开发一个自定义选项卡控件并决定使用 WPF/XAML 创建它,因为我无论如何都打算学习它。完成后应该是这样的: 到目前为止,我取得了很好的进展,但还有两个问题: 只有第一个/最后一个标签项应该有
我要定制xtable用于导出到 LaTeX。我知道有些问题是关于 xtable在这里,但我找不到我要找的具体东西。 以下是我的表的外观示例: my.table <- data.frame(Specif
用ejs在这里显示日期 它给我结果 Tue Feb 02 2016 16:02:24 GMT+0530 (IST) 但是我需要表现为 19th January, 2016 如何在ejs中执行此操作?
我想问在 JavaFX 中使用自定义对象制作 ListView 的最佳方法,我想要一个每个项目如下所示的列表: 我搜了一下,发现大部分人都是用细胞工厂的方法来做的。有没有其他办法?例如使用客户 fxm
我是一名优秀的程序员,十分优秀!