考虑一个大型内存容器。在这个简单的例子中
std::vector v = { 0, 1, 2, 3, 4, 5 };
span允许我在内存上创建一个轻量级视图。现在,我只想打印跨度:
template<typename T>
void print(std::span<T> span) {
std::cout << '[';
if (span.size())
std::copy(span.begin(), span.end() - 1, std::ostream_iterator<int>(std::cout, ", "));
std::cout << span.back() << "]\n";
}
int main() {
std::vector v = { 0, 1, 2, 3, 4, 5 };
print(std::span{ v });
}
输出:
[0, 1, 2, 3, 4, 5]
现在我想制作子集(这是std::span
实际上作为视图变得有用的地方)。我可以使用迭代器来指定我的范围并从std::span
调用这个构造函数(3)
template< class It, class End >
explicit(extent != std::dynamic_extent)
constexpr span( It first, End last );
但这行不通:
print(std::span{ v.begin() + 2, v.end() }); //error E0289
C没有与参数列表匹配的构造函数实例参数类型为:(std::\u Vector\u iterator
有可能使用接受指针和大小的构造函数(2):
print(std::span{ v.data() + 1, 3 }); //-> prints [1, 2, 3]
但这违背了迭代器的目的。
如何使用迭代器构造std::span?我错过什么了吗?
完整代码:
#include <iostream>
#include <vector>
#include <span>
#include <algorithm>
template<typename T>
void print(std::span<T> span) {
std::cout << '[';
if (span.size())
std::copy(span.begin(), span.end() - 1, std::ostream_iterator<int>(std::cout, ", "));
std::cout << span.back() << "]\n";
}
int main() {
std::vector v = { 0, 1, 2, 3, 4, 5 };
print(std::span{ v.begin() + 2, v.end() });
}
在MSVC实现构造函数之前,我将使用此函数:
template<typename It>
constexpr auto make_span(It begin, It end) {
return std::span<std::remove_pointer_t<It::pointer>>(&(*begin), std::distance(begin, end));
}
使用Visual Studio Community 2019版本16.7.5。配置:x64,发布。C语言标准= /std: c最新
您可以使用迭代器构造spans
,它有这样一个构造函数(由P1394添加,您可以在[views.span]中看到):
template< class It, class End >
explicit(extent != std::dynamic_extent)
constexpr span( It first, End last );
只是MSVC的标准库没有实现它。正如预期的那样,该程序在gcc上编译良好。
下面非常简单的代码在C 98中编译和链接时没有警告,但在C 11模式下会出现无法理解的编译错误。 标准=c 11的错误是,gcc版本4.9.0 20140302(实验)(gcc): 带clang版本3.5(trunk 202594) 我一直在看中的代码,我不明白为什么它试图实例化。 为什么在C 11中需要复制构造函数std::pair? 注:上述代码是从不可复制映射的映射迭代器上不支持的等式运算符
我想为客户数据结构提供一个视图,它有自己的迭代器。我编写了一个小程序来测试它,如下所示。如果我取消对begin()的注释,它就会工作。但是如果我使用DummyIter,那么我会得到一个编译错误。 在我的完整程序中,我实现了一个完整的迭代器,但为了简单起见,我把它缩小到了必要的函数。 我使用的是GCC 11.1.0。我在迭代器中缺少了什么使其符合范围?
在MS Visual Studio 2013中使用C 11,我有一个类testNetInfo,它有一个来自std::字符串的非显式构造函数,我想从std::初始化器字符串列表构造这些向量。 如果我从initializer_list构造一个临时向量,我可以用它来设置真正的向量: 但尝试直接从initList创建netInfo时,如下所示:
伊登 JLS所说的是: 设C是ClassName表示的类。设n是一个整数,使得C是类的第n个词汇封闭类,在该类中出现有条件的this表达式。 [...] 如果当前类不是类C或C本身的内部类,则为编译时错误。 在的情况下,内部类集。这意味着上面的代码应该可以正常工作。发生了什么?
我遇到了一个有趣的问题,我不明白发生了什么: 据我所知,我提供的单个整数参数可以解释为使用参数调用构造函数,也可以解释为使用初始化列表的构造函数。似乎只有当我提供左值时才调用initialiser_list构造函数,但当我提供r-value(至少是文字)时,构造函数。为什么会这样? 这也意味着: 结果仅为大小为1的向量; 结果是一个大小为num\u元素的向量,但我认为应该避免这种初始化,因为偶尔会
我想知道为什么c标准要求只接受随机访问迭代器?我不认为这有什么好处,因为std::sort和std::list::sort的复杂性都是。将限制为随机访问迭代器(RAI),似乎需要为具有相同复杂性的列表编写单独的函数。 同样的情况也适用于,其中列表的非RAI计数器部分至今仍然缺失。 这种设计是因为历史上人们使用了的变体来实现? 如果在RAI容器上编写排序算法有好处,那么最好使更通用,并让像这样的RA