일 하다가 텍스트 파일을 파싱한 후 재출력해야 하는 경우가 생겼다.





내용은 대략 이렇다


숫자나 단어들이 whitespace로 끊어져 있는 형태로 나열되어 있고

이 문자열들을 읽어서 알맞은 타입으로 변환해줘야 한다


파일은 대충 이런 형식으로 만 줄 정도



파일의 규격에 대해서는 맨 첫 단어인 Keyword 별로 타입들의 순서가 명시되어 있어서 별 문제는 없어보였다



그래서 tuple 로 묶어서 관리하려고 했다.



잘 진행되다가 에러를 뻗고 죽길래 디버깅해보니 골때리는 경우가 있었다

값이 들어와도 되고 안 들어와도 되는 keyword가 존재했던 것



이걸 해결하려고 고민을 했던 게,


1. 튜플 원소에 optional을 집어넣을까? 

   tuple<double, string, double, optional<int>, optional<double>, ... > 이런식?

이 경우엔 텍스트 파일을 읽다가 단어가 없는 부분을 만나면 

나머지 tuple 원소 갯수만큼 false 로 채워줘야해서 불편했다.

  (1.0, "test", 2.0, 3, false, false, ...)

tuple 원소의 갯수를 들고 있으면서 읽은 단어 수랑 매칭해서 채우기도 애매하고..

나중에 까볼때도 value() 달기 귀찮고.


2. variant로 받은다음 이걸 vector에 넣을까?

   vector<variant<int, double, string>>

이 경우엔 1번보다는 편리해 보였다

타입의 시퀀스는 동일하니까 나중에 풀어낼 때 고민하고 우선은 있는데까지만 받도록



결국 2번으로 결정하고 코드를 돌려서 전부 무사히 읽어냈다


이제는 출력만 하면 됐다

variant 는 visit을 써서 순회하면서 값을 뽑아내면 되니까 쉬울거라고 생각했고 실제로 쉬웠다

포매팅이 필요해서 std::format도 사용해 봤다



근데 이러면 double의 경우 full precision으로 뽑아버려서 포매팅이 망가져 버림

.0 의 값을 가지면 마치 int 처럼 뽑히기도 했다



어차피 문자열은 왼쪽정렬을 하고 싶었어서 타입별로 오버로딩을 시도



잘 뽑혀나와서 마음에 들었다. 



이젠 tuple을 출력할 차례

tuple은 std::apply를 써서 순회한다고 했다

fold expression과 함께 쓰면 간단히 출력할 수 있었다.



여기도 타입별로 출력을 하려고 똑같이 overloaded를 쓰려 했는데 fold expr 안에 람다가 안박힘

내가 뭘 잘못했나


그래서 overloaded 를 람다로 빼서 넣음

하는김에 int, double도 그냥 컨셉을 발라 쓰기로 함




이제서야 만족스럽게 나온다












tlqkf