C++ std::format, std::print 사용법과 컴파일러 호환성

C++20 std::format과 C++23 std::print: 현대적인 문자열 포매팅 C++20과 C++23은 문자열 포매팅을 현대화한 std::format과 std::print를 도입하며, 기존의 printf나 std::cout에 비해 안전하고 직관적인 API를 제공합니다. 이 글에서는 두 기능의 사용법, 컴파일러 호환성, 그리고 지원되지 않는 환경에서 fmt 라이브러리 사용 방법을 다룹니다. 왜 새로운 포매팅 API가 중요한가? 기존 C++ 문자열 포매팅 방법(printf, std::stringstream, std::cout)은 다음과 같은 단점이 있습니다: 안전성 부족: printf는 타입 안정성을 보장하지 않아 런타임 오류 발생 가능. 복잡성: std::stringstream은 장황하고 성능 오버헤드 존재. 가독성: std::cout은 연속적인 << 연산으로 코드가 길어짐. std::format(C++20)과 std::print(C++23)는 Python의 str.format에서 영감을 받아 타입 안전성, 가독성, 성능을 개선했습니다. fmt 라이브러리는 이를 보완하며, 최신 표준을 지원하지 않는 환경에서도 동일한 경험을 제공합니다. ...

May 22, 2025 · Byung Kyu KIM

C++ Lambda 표현식

C++14, C++17, C++20 버전별 Lambda 표현 정리 The Evolutions of Lambdas in C++14, C++17 and C++20 https://www.fluentcpp.com/2021/12/13/the-evolutions-of-lambdas-in-c14-c17-and-c20/{:target="_blank"} 해당 글을 참고하여 예제 자체 작성 C++14 Default parameters #include <iostream> using namespace std; int main() { auto fn = [](int a, int b = 0) { return a + b; }; cout << fn(1) << endl; // 1 cout << fn(1, 2) << endl; // 3 } Template parameters #include <iostream> #include <string> #include <vector> using namespace std; int main() { auto fn = [](auto && c) { return c.size(); }; vector<int> v = {1, 2, 3}; cout << fn(v) << endl; // 3 string s = "12345"; cout << fn(s) << endl; // 5 } Generalised capture #include <iostream> #include <string> using namespace std; int main() { string str = "string"; auto fn = [s = str + "_capture"s](string body) { cout << s << " : " << body << endl; }; fn("test"); // string_capture : test } Returning a lambda from a function #include <iostream> using namespace std; auto getAdd(int n) { return [n](int an) { return n + an; }; } int main() { auto fn = getAdd(10); cout << fn(20) << endl; } C++17 Constexpr #include <iostream> using namespace std; int main() { constexpr auto fn = [](int n){ return n + 10; }; static_assert(fn(10) == 20); // ok static_assert(fn(20) == 20); // error: static assertion failed } Capturing a copy of *this this 참조에 캡쳐가 아닌, *this 복사본 캡쳐 #include <iostream> #include <memory> #include <tuple> using namespace std; class item { public: item(int n = 0) : _value(n) {} auto test() { _value += 1; // copy capture auto fn1 = [*this] { return _value; }; auto fn2 = [self = *this] { return self._value; }; // ref capture auto fn3 = [this] { return _value; }; _value += 1; fn1(); // 11 fn2(); // 11 fn3(); // 12 return make_tuple(fn1, fn2, fn3); } private: int _value; }; int main() { auto it = make_shared<item>(10); auto tp = it->test(); it.reset(); cout << get<0>(tp)() << endl; cout << get<1>(tp)() << endl; cout << get<2>(tp)() << endl; // ref memory error } C++20 Template syntax for lambdas #include <iostream> #include <vector> using namespace std; int main() { auto fn = []<typename T>(vector<T> &v) { return v.size(); }; vector<int> v = {1, 2, 3, 4, 5}; cout << fn(v) << endl; } Lambda capture of parameter pack #include <iostream> #include <string> using namespace std; template <typename... Args> auto getAddFunc(Args&&... args){ // by ref [&...args = std::forward<Args>(args)] // by value return [...args = std::forward<Args>(args)] (auto && init) { return init + (args + ...); }; } int main() { auto fn = getAddFunc(1, 2, 3); cout << fn(10) << endl; // 16 auto fns = getAddFunc("this "s, "is "s, "sample"s); cout << fns("note: "s) << endl; // note: this is sample }

December 14, 2021 · Byung Kyu KIM

C++20 Modules - gnu c++ test

C++ Modules Test Example (g++) C++20 Modules C++20에 추가된 모듈 Modules 기능은 기존의 헤더 파일 #include로 인한 컴파일 시간 증가 문제를 해결하고, 필요한 로직(함수, 심볼)만을 내보내는(export) 방식을 통해 타 언어의 모듈 단위처럼 효율적인 라이브러리 관리를 지원합니다. Modules의 주요 장점 컴파일 시간 단축: 각 모듈은 한 번만 컴파일되며, 그 결과가 캐시됨 심볼 격리: 모듈 내부의 심볼은 명시적으로 export하지 않는 한 외부에서 접근 불가 순환 의존성 방지: 헤더 파일과 달리 명확한 의존성 그래프 형성 매크로 독립성: 모듈은 매크로의 영향을 받지 않아 더 안정적인 코드 작성 가능 일종의 PCH(Precompiled Header)의 기능을 포함한 표준적인 모듈 관리 기능입니다. 현재 컴파일러마다 (MSVC, g++, Clang) Standard Library 지원과 모듈 사용 방법이 약간 상이합니다. ...

September 3, 2021 · Byung Kyu KIM