나는 한 줄짜리를 좋아하기 때문에 (끝에서 볼 수 있듯이 모든 종류의 이상한 일에 매우 유용합니다), 여기 std :: accumulate 및 C ++ 11 lambda를 사용하는 솔루션이 있습니다.
std::accumulate(alist.begin(), alist.end(), std::string(),
[](const std::string& a, const std::string& b) -> std::string {
return a + (a.length() > 0 ? "," : "") + b;
} )
이 구문은 스트림 연산자에 유용하다는 것을 알았습니다. 스트림 작업의 범위를 벗어나는 모든 종류의 이상한 논리를 원하지 않는 단순한 문자열 조인을 수행합니다. 예를 들어 스트림 연산자 (std; 사용)를 사용하여 문자열을 형식화하는 메소드의 다음 return 문을 고려하십시오.
return (dynamic_cast<ostringstream&>(ostringstream()
<< "List content: " << endl
<< std::accumulate(alist.begin(), alist.end(), std::string(),
[](const std::string& a, const std::string& b) -> std::string {
return a + (a.length() > 0 ? "," : "") + b;
} ) << endl
<< "Maybe some more stuff" << endl
)).str();
최신 정보:
주석에서 @plexando가 지적했듯이, 위 코드는 "첫 실행"에 대한 검사에서 추가 문자가없는 이전 실행이 누락되어 배열이 빈 문자열로 시작될 때 잘못된 동작을 겪습니다. 모든 실행에서 "is first run"검사를 실행하는 것은 이상합니다 (즉, 코드가 최적화되지 않음).
목록에 적어도 하나의 요소가 있다는 사실을 알면이 두 가지 문제에 대한 해결책은 쉽습니다. OTOH, 목록에 하나 이상의 요소 가 없다는 사실을 알고 있다면 실행을 더 단축 할 수 있습니다.
결과 코드가 예쁘지 않다고 생각하므로 여기에 The Correct Solution 으로 추가하고 있지만 위의 논의에는 여전히 장점이 있다고 생각합니다.
alist.empty() ? "" :
++alist.begin(), alist.end(),
*alist.begin(),
[](auto& a, auto& b) { return a + "," + b; });
메모:
- 첫 번째 요소에 대한 직접 액세스를 지원하는 컨테이너의 경우 대신 세 번째 인수에 사용하는 것이 좋습니다
alist[0]
.
- 댓글 및 채팅의 토론에 따라 람다는 여전히 일부 복사 작업을 수행합니다. 대신이 (덜 예쁜) 람다를 사용하여 최소화 할 수 있습니다.
[](auto&& a, auto&& b) -> auto& { a += ','; a += b; return a; })
(GCC 10에서) x10 이상으로 성능을 향상시킵니다. 제안에 대해 @Deduplicator에게 감사드립니다. 나는 아직도 여기서 무슨 일이 일어나고 있는지 알아 내려고 노력하고 있습니다.