想象我有std::vector
的{{1}},并且我想在基于范围的for循环中将这些std::string
转换为std::string
:
std::string_view
上面的代码是完全有效的,但是我想保留auto v = std::vector<std::string>{"abc", "def", "ghi"};
for (std::string_view sv : v) {
// do something with string_view
}
说明符来执行此操作,如何在基于行范围的for循环中执行auto
这样呢?看来C ++ 20 static_cast
可以用简洁的方式做到这一点,有人可以举个例子吗?
ranges
答案 0 :(得分:5)
并不是说这是一个好主意,但这可能是一个更通用的 transform 概念(以及一个邪恶的lambda技巧)的有用示例:
for(auto sv : v |
views::transform([](std::string_view x) {return x;})) …
答案 1 :(得分:2)
作为@Elijay的评论,您可以简单地创建vector
中的新string_view
:
for (auto sv : vector<string_view>(v.begin(), v.end()))
但是,这种做法打败了首先使用string_view
的整个目的:避免复制。
如下所述,它也有悖于auto
的全部目的:避免不必要地重述类型信息。这里是首次引入类型,因此必须明确声明 。为什么不直接在普通视图中查看
开始时要避免冗长,并按预期使用string_view
:
for (string_view sv : v)
答案 2 :(得分:2)
您可以执行以下操作:
#include <string>
#include <vector>
#include <iostream>
#include <string_view>
int main() {
auto v = std::vector<std::string>{"abc", "def", "ghi"};
for (auto sv : std::vector<std::string_view>(v.begin(), v.end())) {
// use sv ...
}
}
但是请注意,完全不建议创建一个新的向量。它会再次分配内存,并导致大量不必要的开销。此外,您仍然必须在任何地方拼写该类型,因此auto
在这里根本没有任何优势。 Right Thing TM 要做的是显式指定类型名称,而不使用auto
。
答案 3 :(得分:1)
迭代器是一个很好的自定义点,不幸的是,它需要很多样板:
Output -
40934
39709.714285714
39052.530612245
38644.463556851
39409.10120783
40071.972808949
41075.540353084
答案 4 :(得分:0)
可以说是简明扼要。意见会有所不同。
#include <vector>
#include <string_view>
#include <string>
#include <iostream>
#include <range/v3/view/transform.hpp>
int main()
{
auto v = std::vector<std::string>{"abc", "def", "ghi"};
using namespace ranges;
auto as_string_view = views::transform([](auto&& x) { return std::string_view(x); });
for (auto sv : v | as_string_view) {
std::cout << sv << '\n';
}
}