具有自动说明符和static_cast的基于范围的for循环

时间:2019-12-07 16:44:56

标签: c++ for-loop auto c++20

想象我有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

5 个答案:

答案 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';
    } 
}