본문으로 바로가기

std::ranges 를 이용한 split 구현

category C++/여담 2021. 8. 25. 04:02
std::vector <std::string> split(std::string_view str, std::string_view delim) {
	auto view{ str
	| std::ranges::views::split(delim)
	| std::ranges::views::transform([](auto&& elem) {
			return std::string_view(&*elem.begin(), std::ranges::distance(elem));
	}) };

	std::vector<std::string> strings{ view.begin(), view.end() };
	return strings;
}

int main() {
	for (auto& elem : split("HI, MY, NAME, IS, UM", ", ")) {
		std::cout << elem << std::endl;
	}
}

std::ranges::split_view는 실제로는 데이터와 delimiter만 가지고 있다.

이를 실제로 나누는 작업은 transform에서 일어나게 되는데,

std::ranges::views::transform 에서 elem은 std::split_view -> ranges 이다.

그로 인해 begin()에 접근하면 split_view의 iterator이고, operator*는 const char& 이다.

즉 ' &*elem.begin() ' 은 나뉘어진 char의 맨 첫번째 이다. (ranges의 [0]번째 라고 보면 된다.)


std::ranges::views::transform에 넘어오는 인자는 총 다섯개 (HI, MY, NAME, IS, UM) 이다. (ranges)

이때 &*elem.begin() 은 'H, M, N, I, U' 이며, distance는 (2, 2, 4, 2, 2) 이다.

string_view의 생성자를 보면..

이렇게 char* 와 count를 가지고 구성할 수 있다.

 

그래서 나오는 결과는

HI

MY

NAME

IS

UM

이다.

 

데이터는 실제로 iterator가 구성될 때 나누게 된다.