From 01a3734edcc9dafcdca0511a5590aad2f0a747bb Mon Sep 17 00:00:00 2001 From: jabdong4ny Date: Mon, 11 Mar 2024 04:48:44 +0900 Subject: [PATCH 01/30] =?UTF-8?q?F.call:=20=EB=A7=A4=EA=B0=9C=EB=B3=80?= =?UTF-8?q?=EC=88=98=20=EC=A0=84=EB=8B=AC(Parameter=20passing)=20=EB=B2=88?= =?UTF-8?q?=EC=97=AD=20=EC=B5=9C=EC=8B=A0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sections/Functions.md | 298 ++++++++++++++++++++++++++---------------- 1 file changed, 187 insertions(+), 111 deletions(-) diff --git a/sections/Functions.md b/sections/Functions.md index 63d5c5b..9eb6c23 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -35,6 +35,7 @@ * [F.19: "전달(forward)" 매개변수는 `TP&&`타입과 `std::forward`로만 전달하라](#Rf-forward) * [F.20: "출력(out)"에는 매개변수보다는 값을 반환하는 방법을 선호하라](#Rf-out) * [F.21: "출력"값 여러 개를 반환할 때는 튜플이나 구조체를 선호하라](#Rf-out-multi) +* [F.60: "인자가 없을 경우"를 허용한다면 `T&`보다는 `T*`를 선호하라](#Rf-ptr-ref) 매개변수 전달 의미구조(parameter passing semantic) 규칙: @@ -44,7 +45,6 @@ * [F.25: C 스타일 문자열에는 `zstring` 혹은 `not_null`을 사용하라](#Rf-zstring) * [F.26: 포인터가 필요한 곳에 소유권을 전달할 때는 `unique_ptr`를 사용하라](#Rf-unique_ptr) * [F.27: 소유권을 공유할 때는 `shared_ptr`를 사용하라](#Rf-shared_ptr) -* [F.60: "인자가 없을 경우"를 허용한다면 `T&`보다는 `T*`를 선호하라](#Rf-ptr-ref) 값 반환 의미구조 규칙: @@ -55,6 +55,7 @@ * [F.46: `main()`는 `int`를 반환해야 한다](#Rf-main) * [F.47: 대입 연산자는 `T&`를 반환하라](#Rf-assignment-op) * [F.48: `return std::move(local)`은 사용하지 말아라](#Rf-return-move-local) +* [F.49: `return const T`는 사용하지 말아라](#Rf-return-const) 기타 함수 규칙: @@ -539,6 +540,12 @@ C++14 에서는 이와 같이 작성할 수 있다. C++ 11 환경이라면, `fac 필요한 경우에만 고급 기술을 사용하고, 주석으로 문서화하라. +문자열 전달은 [String](#SS-string) 참고. + +##### Exception + +`shared_ptr` 타입을 사용한 공유 소유권을 표현하려면 F.16-21 지침을 따르기보다는 [R.34](#Rr-sharedptrparam-owner), [R.35](#Rr-sharedptrparam) 및 [R.36](#Rr-sharedptrparam-const)을 따르세요. + ### F.16: "입력(in)" 매개변수는 복사 비용이 적게 드는 타입의 경우 값으로 전달하고, 그 외에는 상수 참조형으로 전달하라 ##### Reason @@ -578,39 +585,22 @@ C++14 에서는 이와 같이 작성할 수 있다. C++ 11 환경이라면, `fac void sink(unique_ptr); // input only, and moves ownership of the widget ``` -아래와 같은 "난해한 기술"은 지양하라: - -* "효율적이라서" 인자를 `T&&`로 전달한다. `&&`로 전달함으로써 발생하는 성능 향상에 대한 루머는 잘못되었고 깨지기 쉽다(속단하지 말고 [F.18](#Rf-consume)와 [F.19](#Rf-forward)를 참고하라) -* 대입에서 `const T&`를 반환하거나 비슷한 연산을 수행한다 ([F.47](#Rf-assignment-op) 참고) - -##### Example - -`Matrix`가 이동 연산을 지원한다고 가정하자(아마도 원소들을 `std::vector`에 보관하고 있다): - -```c++ - Matrix operator+(const Matrix& a, const Matrix& b) - { - Matrix res; - // ... fill res with the sum ... - return res; - } - - Matrix x = m1 + m2; // move constructor - - y = m3 + m3; // move assignment -``` +"효율적이라서" 인자를 `T&&`로 전달한다. `&&`로 전달함으로써 발생하는 성능 향상에 대한 루머는 잘못되었고 깨지기 쉽다(속단하지 말고 [F.18](#Rf-consume)와 [F.19](#Rf-forward)를 참고하라) ##### Notes -반환 값 최적화는 대입에 대해서는 동작하지 않지만, 이동 대입의 경우에는 적용된다. 참조는 언어 규칙에 의해 유효한 개체를 가리킨다고 가정하기 때문에, null 참조는 발생하지 않는다. optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::optional` 혹은 "값이 없음"을 의미하는 특별한 값을 사용하라. ##### Enforcement -* (쉬움) (기본 사항) 인자의 크기가 `4 * sizeof(int)` 보다 크면 경고한다. `const` 참조를 전달하도록 제안한다 -* (쉬움) (기본 사항) `const` 참조로 전달되는 인자의 크기가 `3 * sizeof(int)`보다 작다면 경고한다. 값 전달을 대신 사용하도록 제안한다 -* (쉬움) (기본 사항) `const` 참조 매개변수가 `move`되면 경고한다 +* (쉬움) (기본 사항) 인자의 크기가 `2 * sizeof(void*)` 보다 크면 경고한다. 대신 `const` 참조를 전달하도록 제안한다. +* (쉬움) (기본 사항) `const` 참조로 전달되는 인자의 크기가 `2 * sizeof(void*)` 이하면 경고한다. 대신 값을 전달하도록 제안한다. +* (쉬움) (기본 사항) `const` 참조 매개변수가 `move`되면 경고한다. + +##### Exception + +`shared_ptr` 유형을 사용하여 공유 소유권을 표현하려면 함수가 전달인자를 참조하는지 여부에 따라 [R.34](#Rr-sharedptrparam-owner) 또는 [R.36](#Rr-sharedptrparam-const)을 따르세요. ### F.17: "입출력(in-out)" 매개변수는 비상수 참조형으로 전달하라 @@ -626,6 +616,18 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt ##### Note +일부 사용자 정의 및 표준 라이브러리 유형은 `span`나 반복자와 같이 [복사 비용이 저렴](#Rf-in)하고 값으로 전달될 수 있지만, 변경 가능한(in-out) 참조 의미론을 가지고 있다: + +```c++ + void increment_all(span a) + { + for (auto&& e : a) + ++e; + } +``` + +##### Note + `T&` 인자는 정보를 전달할 수도 있지만 받아올 수도 있다. 때문에 `T&`는 입출력 매개변수가 될 수 있다. 이로 인해 문제가 되거나 오류의 원인이 되기도 한다: @@ -649,7 +651,7 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt ##### Enforcement * (중간) (기본 사항) 함수 내에서 값을 변경하지 않는 비 `const` 참조를 경고한다 -* (쉬움) (기본 사항) `const` 참조 매개변수가 `move`되면 경고한다 +* (쉬움) (기본 사항) 비 `const` 참조 매개변수가 `move`되면 경고한다 ### F.18: "넘겨주는(will-move-from)" 매개변수는 `X&&`타입과 `std::move`로 전달하라 @@ -683,6 +685,10 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt } // p gets destroyed ``` +##### Exception + +"will-move-from" 매개 변수가 `shared_ptr`이면 [R.34](#Rr-sharedptrparam-owner)를 따르고 `shared_ptr`을 값으로 전달한다. + ##### Enforcement * 모든 `std::move`없이 `X&&` 매개변수를 사용하면 지적한다 (이때 `X`는 템플릿 인자가 아니다) @@ -699,18 +705,33 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt ##### Example +일반적으로 모든 정적 제어 흐름 경로에서 전체 매개변수(또는 인자 묶음(pack), 또는 `...` 사용)를 정확히 한 번 전달합니다: + ```c++ - template - inline auto invoke(F f, Args&&... args) { - return f(forward(args)...); + template + inline decltype(auto) invoke(F&& f, Args&&... args) + { + return forward(f)(forward(args)...); } +``` + +##### Example + +때로는 모든 정적 제어 흐름 경로에서 복합 매개 변수의 각 하위 개체를 한 번씩 전달할 수 있습니다: - ??? calls ??? +```c++ + template + inline auto test(PairLike&& pairlike) + { + // ... + f1(some, args, and, forward(pairlike).first); // forward .first + f2(and, forward(pairlike).second, in, another, call); // forward .second + } ``` ##### Enforcement -* 모든 정적 경로에 대해 단 한번 `std::forward`하는 경우를 제외하고 `TP&&` 매개변수를 받는 함수를 지적한다 (`TP`는 템플릿 인자의 이름이다). +* 모든 정적 경로에 대해 단 한번 `std::forward`하는 경우를 제외하고 `TP&&` 매개변수를 받는 함수를 지적한다. (`TP`는 템플릿 인자의 이름이다) 또는 `std::forward`을 한 번 이상 수행하지만 정적 경로마다 정확히 한 번씩 다른 데이터 멤버로 자격을 부여한다. ### F.20: "출력(out)"에는 매개변수보다는 값을 반환하는 방법을 선호하라 @@ -736,28 +757,32 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt (각각의 이동 비용이 크지 않은) 멤버를 많이 가진 `struct`는 전체적으로는 이동 비용이 클 수 있다. -`const` 값을 반환하는 것은 추천하지 않는다. 오래된 조언들은 무의미하다: 의미도 없고 이동 의미구조를 방해한다. +##### Exceptions -```c++ - const vector fct(); // bad: that "const" is more trouble than it is worth +* 상속 계층구조에 속한 타입처럼 값 타입이 아닌 경우, 개체를 `unique_ptr` 혹은 `shared_ptr`로 반환하라 +* 많약 값의 이동 비용이 크다면 (`array` 같은 경우), 자유 저장소에 할당하고 그 핸들을 (`unique_ptr`와 같은) 반환하는 것을 고려하라. 또는 `const`가 아닌 참조(출력 매개변수)를 전달해 개체를 채워넣도록 하라 +* 최대 크기(capacity)를 가진 개체(예를 들어 `std::string`, `std::vector`)를 여러 함수 호출과정에서 재사용하고자 한다면, [입출력 매개변수로 참조를 전달하라](#Rf-out-multi). - vector g(const vector& vx) +##### Example + +`Matrix`가 이동 연산을 지원한다고 가정하자(아마도 원소들을 `std::vector`에 보관하고 있다): + +```c++ + Matrix operator+(const Matrix& a, const Matrix& b) { - // ... - fct() = vx; // prevented by the "const" - // ... - return fct(); // expensive copy: move semantics suppressed by the "const" + Matrix res; + // ... fill res with the sum ... + return res; } -``` -반환 값에 `const`를 사용하는 것은 임시 변수에 대한 (굉장히 드문) 우발적 접근을 막기 위한 것이다. -전달 인자에 `const`가 사용되면 (매우 자주 발생하는) 이동 의미구조를 막는다. + Matrix x = m1 + m2; // move constructor -##### Exceptions + y = m3 + m3; // move assignment +``` -* 상속 계층구조에 속한 타입처럼 값 타입이 아닌 경우, 개체를 `unique_ptr` 혹은 `shared_ptr`로 반환하라 -* 많약 값의 이동 비용이 크다면 (`array` 같은 경우), 자유 저장소에 할당하고 그 핸들을 (`unique_ptr`와 같은) 반환하는 것을 고려하라. 또는 `const`가 아닌 참조(출력 매개변수)를 전달해 개체를 채워넣도록 하라 -* 최대 크기(capacity)를 가진 개체(예를 들어 `std::string`, `std::vector`)를 여러 함수 호출과정에서 재사용하고자 한다면, [입출력 매개변수로 참조를 전달하라](#Rf-out-multi). +##### Notes + +반환 값 최적화는 대입에 대해서는 동작하지 않지만, 이동 대입의 경우에는 적용된다. ##### Example @@ -777,15 +802,12 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt ##### Enforcement * 큰 비용 없이 반환할 수 있으면서 값을 변경하기 전에 사용하는 비 `const` 참조 매개변수를 지적하라; 이들은 "출력" 반환 값이 적절하다. -* `const` 반환 값을 지적한다. `const`를 제거하도록 권한다 ### F.21: "출력"값 여러 개를 반환할 때는 튜플이나 구조체를 선호하라 ##### Reason -반환 값은 그 자체로 문서가 필요하지 않고 "출력 전용"으로 사용된다. -C++ 에서는 다수의 값을 반환할때는 `tuple`(`pair`를 포함해)를 쓴다는 것을 기억하라, 호출한 지점에서 `tie`를 사용해 받을 것이다. -반환 값에 의미구조가 있다면 별도의 struct 타입을 사용하라. 그렇지 않다면 일반적인 코드에서는 (이름 없는) `tuple`이 유용하다. +반환 값은 그 자체로 문서가 필요하지 않고 "출력 전용"으로 사용된다. C++ 에서는 다수의 값을 반환할때는 튜플과 유사한 유형(`struct`, `array`, `tuple` 등)를 쓴다는 것을 기억하라, 호출한 지점에서 구조화된 바인딩(structured bindings)(C++17)을 추가로 편리하게 사용할 수 있다. 반환 값에 의미구조가 있다면 별도의 `struct` 타입을 사용하라. 그렇지 않다면 일반적인 코드에서는 (이름 없는) `tuple`이 유용하다. ##### Example @@ -799,39 +821,33 @@ C++ 에서는 다수의 값을 반환할때는 `tuple`(`pair`를 포함해)를 } // GOOD: self-documenting - tuple f(const string& input) + struct f_result { int status; string data; }; + + f_result f(const string& input) { // ... - return make_tuple(status, something()); + return {status, something()}; } ``` -사실, C++98의 표준 라이브러리에서는 `pair`가 개체 2개를 묶은 `tuple`과 같기 때문에 이 기능을 편리하게 사용하고 있었다. - -예를 들어, `set my_set`이 주어졌다고 가정하면: +C++98의 표준 라이브러리에서는 일부 함수에서 `pair`를 반환하는 스타일을 사용했다. 예를 들어, `set my_set`이 주어졌다고 가정하면: ```c++ // C++98 - result = my_set.insert("Hello"); - if (result.second) do_something_with(result.first); // workaround -``` - -C++11에서는 이렇게 작성할 수 있다, 결과값들을 이미 존재하는 지역변수에 대입한다: - -```c++ - Sometype iter; // default initialize if we haven't already - Someothertype success; // used these variables for some other purpose - - tie(iter, success) = my_set.insert("Hello"); // normal return value - if (success) do_something_with(iter); + pair result = my_set.insert("Hello"); + if (result.second) + do_something_with(result.first); // workaround ``` C++ 17에서는 다수의 변수들을 선언과 동시에 초기화 할 수 있는 "structured bindings"을 지원한다: ```c++ - if (auto [ iter, success ] = my_set.insert("Hello"); success) do_something_with(iter); + if (auto [ iter, success ] = my_set.insert("Hello"); success) + do_something_with(iter); ``` +모던 C++에서는 의미 있는 이름을 가진 `struct`가 더 일반적입니다. 예를 들어 `ranges::min_max_result`, `from_chars_result` 등을 참조. + ##### Exception 때에 따라서는 개체의 상태를 변경하기 위해 함수에 개체를 전달해야 할 수도 있다. @@ -856,16 +872,18 @@ C++ 17에서는 다수의 변수들을 선언과 동시에 초기화 할 수 있 비교를 위해, 값을 반환하는 방법으로 해결한다면 아래와 같이 작성하게 될 것이다: ```c++ - pair get_string(istream& is); // not recommended + struct get_string_result { istream& in; string s; }; + + get_string_result get_string(istream& in) // not recommended { string s; - is >> s; - return {is, s}; + in >> s; + return { in, move(s) }; } - for (auto p = get_string(cin); p.first; ) { - // do something with p.second - } + for (auto [in, s] = get_string(cin); in; s = get_string(in).s) { + // do something with string + } ``` 생각보다 아름답지 않고 성능에도 좋지 않다. @@ -892,11 +910,73 @@ C++ 17에서는 다수의 변수들을 선언과 동시에 초기화 할 수 있 추상화가 아닌 독립적인 존재들(independent entities)을 표현할 때는 `pair`와 `tuple`은 필요 이상으로 범용적(overly-generic)일 수 있다. -다른 예로는, `tuple`대신 특정 타입과 비슷한 `variant`를 사용하라. +다른 옵션은 `pair`와 `tuple`이 아닌 `optional` 또는 `expected`를 사용하는 것입니다. 적절하게 사용될 때 이러한 유형은 `pair` 또는 `pair`보다 멤버들이 무엇을 의미하는지에 대한 더 많은 정보를 전달한다. + +##### Note + +반환할 개체가 복사 비용이 많이 드는 로컬 변수에서 초기화되는 경우 명시적인 `move`가 복사를 피하는 데 도움이 될 수 있다: + +```c++ + pair f(const string& input) + { + LargeObject large1 = g(input); + LargeObject large2 = h(input); + // ... + return { move(large1), move(large2) }; // no copies + } +``` + +다른 방법으로는, + +```c++ + pair f(const string& input) + { + // ... + return { g(input), h(input) }; // no copies, no moves + } +``` +##### Note + +이는 [ES.56](#Res-move)의 `return move(...)` 안티 패턴과 다르다. ##### Enforcement * 출력 목적의 매개변수는 반환값으로 대체되어야 한다. 출력 매개변수는 함수(멤버함수 포함)에서 값을 변경하는 `const`가 아닌 매개변수를 의미한다. +* 가능하다면 `pair` 또는 `tuple` 반환 유형은 `struct`로 대체되어야 한다. 변형 템플릿에서 `tuple`은 종종 피할 수 없다. + +### F.60: "인자가 없을 경우"를 허용한다면 `T&`보다는 `T*`를 선호하라 + +##### Reason + +포인터(`T*`)는 `nullptr`일 수 있지만, 참조(`T&`)는 그렇지 않다. +경우에 따라서는 "개체 없음"을 표시하기 위해 `nullptr`를 사용하는 것이 유용할 수 있다. 그렇지 않다면, 참조가 더 간단하고 좋은 코드로 이어질 것이다. + +##### Example + +```c++ + string zstring_to_string(zstring p) // zstring is a char*; that is a C-style string + { + if (!p) return string{}; // p might be nullptr; remember to check + return string{p}; + } + + void print(const vector& r) + { + // r refers to a vector; no check needed + } +``` + +##### Note + +가능하기는 하지만, C++에서 `nullptr`인 개체를 생성하는 것은 정상적(valid)이지 않다(예를 들어, `T* p = nullptr; T& r = (T&)*p;`). 그런 오류는 굉장히 드물다(very uncommon). + +##### Note + +포인터 표기법을 선호한다면 (`.`보다는 `->` 혹은 `*`가 좋다면), `not_null`이 `T&`처럼 사용될 수 있다. + +##### Enforcement + +??? ### F.22: T* 혹은 owner를 단일 개체를 지정하기 위해 사용하라 @@ -1159,41 +1239,6 @@ Consider: (실행 불가) 제대로 탐지하기엔 너무 복잡한 패턴을 띄고 있다. -### F.60: "인자가 없을 경우"를 허용한다면 `T&`보다는 `T*`를 선호하라 - -##### Reason - -포인터(`T*`)는 `nullptr`일 수 있지만, 참조(`T&`)는 그렇지 않다. -경우에 따라서는 "개체 없음"을 표시하기 위해 `nullptr`를 사용하는 것이 유용할 수 있다. 그렇지 않다면, 참조가 더 간단하고 좋은 코드로 이어질 것이다. - -##### Example - -```c++ - string zstring_to_string(zstring p) // zstring is a char*; that is a C-style string - { - if (!p) return string{}; // p might be nullptr; remember to check - return string{p}; - } - - void print(const vector& r) - { - // r refers to a vector; no check needed - } -``` - -##### Note - - -가능하기는 하지만, C++에서 `nullptr`인 개체를 생성하는 것은 정상적(valid)이지 않다(예를 들어, `T* p = nullptr; T& r = (T&)*p;`). 그런 오류는 굉장히 드물다(very uncommon). - -##### Note - -포인터 표기법을 선호한다면 (`.`보다는 `->` 혹은 `*`가 좋다면), `not_null`이 `T&`처럼 사용될 수 있다. - -##### Enforcement - -??? - ### F.42: 위치를 나타내는 경우에만 `T*`를 반환하라 ##### Reason @@ -1527,6 +1572,37 @@ Guaranteed copy elision이 적용되면 `std::move`를 반환 구문에 사용 반환 구문을 검사하는 도구에 의해서 검사되어야 한다. +### F.49: `return const T`는 사용하지 말아라 + +##### Reason + +`const` 값을 반환하는 것은 추천하지 않는다. 오래된 조언들은 무의미하다; 의미도 없고 이동 의미구조를 방해한다. + +##### Example + +```c++ + const vector fct(); // bad: that "const" is more trouble than it is worth + + vector g(const vector& vx) + { + // ... + fct() = vx; // prevented by the "const" + // ... + return fct(); // expensive copy: move semantics suppressed by the "const" + } +``` + +반환 값에 `const`를 사용하는 것은 임시 변수에 대한 (굉장히 드문) 우발적 접근을 막기 위한 것이다. +전달 인자에 `const`가 사용되면 (매우 자주 발생하는) 이동 의미구조를 막는다. + +##### See also + +[F.20: 출력 값 "out"에 대한 일반 항목](#Rf-out) + +##### Enforcement + +* `const` 반환 값을 지적한다. `const`를 제거하도록 권한다. + ### F.50: 함수를 쓸 수 없을 때는 람다를 사용하라(지역 변수를 캡쳐하거나 지역 함수를 작성할 때) ##### Reason From 9275ba30f623b41eb970df26324acc4dc11d6fce Mon Sep 17 00:00:00 2001 From: jabdong4ny Date: Wed, 13 Mar 2024 06:03:34 +0900 Subject: [PATCH 02/30] =?UTF-8?q?F.call:=20=EB=A7=A4=EA=B0=9C=EB=B3=80?= =?UTF-8?q?=EC=88=98=20=EC=A0=84=EB=8B=AC(Parameter=20passing)=20=EB=B2=88?= =?UTF-8?q?=EC=97=AD=20=EC=B5=9C=EC=8B=A0=ED=99=94=20*=20#147=20=EC=A7=80?= =?UTF-8?q?=EC=B9=A8=EC=97=90=20=EB=A7=9E=EA=B2=8C=20=EB=A7=81=ED=81=AC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sections/Functions.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sections/Functions.md b/sections/Functions.md index 9eb6c23..0e58d7c 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -470,7 +470,7 @@ C++14 에서는 이와 같이 작성할 수 있다. C++ 11 환경이라면, `fac ##### See also -* [전달인자가 없는 경우가 허용된다면 `T&`보다는 `T*`를 선호하라](#Rf-ptr-ref) +* [전달인자가 없는 경우가 허용된다면 `T&`보다는 `T*`를 선호하라](./Expr.md/#Rf-ptr-ref) * [스마트 포인터 규칙 요약](./Resource.md#Rr-summary-smartptrs) ##### Enforcement @@ -544,7 +544,7 @@ C++14 에서는 이와 같이 작성할 수 있다. C++ 11 환경이라면, `fac ##### Exception -`shared_ptr` 타입을 사용한 공유 소유권을 표현하려면 F.16-21 지침을 따르기보다는 [R.34](#Rr-sharedptrparam-owner), [R.35](#Rr-sharedptrparam) 및 [R.36](#Rr-sharedptrparam-const)을 따르세요. +`shared_ptr` 타입을 사용한 공유 소유권을 표현하려면 F.16-21 지침을 따르기보다는 [R.34](./References.md/#Rr-sharedptrparam-owner), [R.35](./References.md/#Rr-sharedptrparam) 및 [R.36](./References.md/#Rr-sharedptrparam-const)을 따르세요. ### F.16: "입력(in)" 매개변수는 복사 비용이 적게 드는 타입의 경우 값으로 전달하고, 그 외에는 상수 참조형으로 전달하라 @@ -600,7 +600,7 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt ##### Exception -`shared_ptr` 유형을 사용하여 공유 소유권을 표현하려면 함수가 전달인자를 참조하는지 여부에 따라 [R.34](#Rr-sharedptrparam-owner) 또는 [R.36](#Rr-sharedptrparam-const)을 따르세요. +`shared_ptr` 유형을 사용하여 공유 소유권을 표현하려면 함수가 전달인자를 참조하는지 여부에 따라 [R.34](./References.md/#Rr-sharedptrparam-owner) 또는 [R.36](./References.md/#Rr-sharedptrparam-const)을 따르세요. ### F.17: "입출력(in-out)" 매개변수는 비상수 참조형으로 전달하라 @@ -687,7 +687,7 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt ##### Exception -"will-move-from" 매개 변수가 `shared_ptr`이면 [R.34](#Rr-sharedptrparam-owner)를 따르고 `shared_ptr`을 값으로 전달한다. +"will-move-from" 매개 변수가 `shared_ptr`이면 [R.34](./References.md/#Rr-sharedptrparam-owner)를 따르고 `shared_ptr`을 값으로 전달한다. ##### Enforcement From 5e2867cee000f57e67b654d49184b9941ef39e89 Mon Sep 17 00:00:00 2001 From: Park DongHa Date: Sat, 16 Mar 2024 13:49:27 +0900 Subject: [PATCH 03/30] Update sections/Functions.md --- sections/Functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index 0e58d7c..fb71d06 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -544,7 +544,7 @@ C++14 에서는 이와 같이 작성할 수 있다. C++ 11 환경이라면, `fac ##### Exception -`shared_ptr` 타입을 사용한 공유 소유권을 표현하려면 F.16-21 지침을 따르기보다는 [R.34](./References.md/#Rr-sharedptrparam-owner), [R.35](./References.md/#Rr-sharedptrparam) 및 [R.36](./References.md/#Rr-sharedptrparam-const)을 따르세요. +`shared_ptr` 타입을 사용한 공유 소유권을 표현하려면 F.16-21 지침을 따르기보다는 [R.34](./References.md/#Rr-sharedptrparam-owner), [R.35](./References.md/#Rr-sharedptrparam) 및 [R.36](./References.md/#Rr-sharedptrparam-const)을 참고하라. ### F.16: "입력(in)" 매개변수는 복사 비용이 적게 드는 타입의 경우 값으로 전달하고, 그 외에는 상수 참조형으로 전달하라 From 7317195fc69495e8589733c42b773061eb032dda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Tue, 19 Mar 2024 09:20:15 +0900 Subject: [PATCH 04/30] Update sections/Functions.md Co-authored-by: Park DongHa --- sections/Functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index fb71d06..a34aab2 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -55,7 +55,7 @@ * [F.46: `main()`는 `int`를 반환해야 한다](#Rf-main) * [F.47: 대입 연산자는 `T&`를 반환하라](#Rf-assignment-op) * [F.48: `return std::move(local)`은 사용하지 말아라](#Rf-return-move-local) -* [F.49: `return const T`는 사용하지 말아라](#Rf-return-const) +* [F.49: `const T`는 `return`에 사용하지 말아라](#Rf-return-const) 기타 함수 규칙: From ef24b3b3bac3d668ab9b40484d6f5bf973ecd992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Tue, 19 Mar 2024 09:20:31 +0900 Subject: [PATCH 05/30] Update sections/Functions.md Co-authored-by: Park DongHa --- sections/Functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index a34aab2..9786464 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -540,7 +540,7 @@ C++14 에서는 이와 같이 작성할 수 있다. C++ 11 환경이라면, `fac 필요한 경우에만 고급 기술을 사용하고, 주석으로 문서화하라. -문자열 전달은 [String](#SS-string) 참고. +문자열 전달은 [String](./SL.md#SS-string) 참고. ##### Exception From b1b77a32c4b285542a19e4d1f6e0c914f63cdd01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Tue, 19 Mar 2024 09:21:05 +0900 Subject: [PATCH 06/30] Update sections/Functions.md Co-authored-by: Park DongHa --- sections/Functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index 9786464..cdeb56e 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -600,7 +600,7 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt ##### Exception -`shared_ptr` 유형을 사용하여 공유 소유권을 표현하려면 함수가 전달인자를 참조하는지 여부에 따라 [R.34](./References.md/#Rr-sharedptrparam-owner) 또는 [R.36](./References.md/#Rr-sharedptrparam-const)을 따르세요. +`shared_ptr` 타입을 사용하여 공유 소유권을 표현하려면 함수가 전달인자를 참조하는지 여부에 따라 [R.34](./References.md/#Rr-sharedptrparam-owner) 또는 [R.36](./References.md/#Rr-sharedptrparam-const)를 참고하라. ### F.17: "입출력(in-out)" 매개변수는 비상수 참조형으로 전달하라 From d91b0d4672802d2b42264443426e30d9552f50ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Tue, 19 Mar 2024 09:21:14 +0900 Subject: [PATCH 07/30] Update sections/Functions.md Co-authored-by: Park DongHa --- sections/Functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index cdeb56e..0c8d5ee 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -616,7 +616,7 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt ##### Note -일부 사용자 정의 및 표준 라이브러리 유형은 `span`나 반복자와 같이 [복사 비용이 저렴](#Rf-in)하고 값으로 전달될 수 있지만, 변경 가능한(in-out) 참조 의미론을 가지고 있다: +일부 사용자 정의 및 표준 라이브러리 타입은 `span`나 반복자와 같이 [복사 비용이 저렴](#Rf-in)하고 값으로 전달될 수 있지만, 변경 가능한(in-out) 참조 의미론(semantics)을 가지고 있다: ```c++ void increment_all(span a) From 85ec46a9b01976ba4acfa80d1c7a7423098ad086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Tue, 19 Mar 2024 09:21:25 +0900 Subject: [PATCH 08/30] Update sections/Functions.md Co-authored-by: Park DongHa --- sections/Functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index 0c8d5ee..11f589d 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -910,7 +910,7 @@ C++ 17에서는 다수의 변수들을 선언과 동시에 초기화 할 수 있 추상화가 아닌 독립적인 존재들(independent entities)을 표현할 때는 `pair`와 `tuple`은 필요 이상으로 범용적(overly-generic)일 수 있다. -다른 옵션은 `pair`와 `tuple`이 아닌 `optional` 또는 `expected`를 사용하는 것입니다. 적절하게 사용될 때 이러한 유형은 `pair` 또는 `pair`보다 멤버들이 무엇을 의미하는지에 대한 더 많은 정보를 전달한다. +다른 옵션은 `pair`와 `tuple`이 아닌 `optional` 또는 `expected`를 사용하는 것입니다. 적절하게 사용될 때 이러한 타입은 `pair` 또는 `pair`보다 멤버들의 의도에 대한 더 많은 정보를 전달한다. ##### Note From fcfb310e4928e0556045fa4d819013fae7aa2439 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Tue, 19 Mar 2024 09:21:34 +0900 Subject: [PATCH 09/30] Update sections/Functions.md Co-authored-by: Park DongHa --- sections/Functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index 11f589d..c46c22f 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -942,7 +942,7 @@ C++ 17에서는 다수의 변수들을 선언과 동시에 초기화 할 수 있 ##### Enforcement * 출력 목적의 매개변수는 반환값으로 대체되어야 한다. 출력 매개변수는 함수(멤버함수 포함)에서 값을 변경하는 `const`가 아닌 매개변수를 의미한다. -* 가능하다면 `pair` 또는 `tuple` 반환 유형은 `struct`로 대체되어야 한다. 변형 템플릿에서 `tuple`은 종종 피할 수 없다. +* 가능하다면 `pair` 또는 `tuple` 반환 유형은 `struct`로 대체되어야 한다. 변형 템플릿에서는 `tuple`을 사용할 수 밖에 없다. ### F.60: "인자가 없을 경우"를 허용한다면 `T&`보다는 `T*`를 선호하라 From ae229a9a0a6b62e7045cee67eb05e6a352bbe99b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Tue, 19 Mar 2024 09:21:43 +0900 Subject: [PATCH 10/30] Update sections/Functions.md Co-authored-by: Park DongHa --- sections/Functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index c46c22f..96b3f9f 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -1601,7 +1601,7 @@ Guaranteed copy elision이 적용되면 `std::move`를 반환 구문에 사용 ##### Enforcement -* `const` 반환 값을 지적한다. `const`를 제거하도록 권한다. +* `const` 값을 반환에 사용하면 지적한다. `const`를 제거하도록 권한다. ### F.50: 함수를 쓸 수 없을 때는 람다를 사용하라(지역 변수를 캡쳐하거나 지역 함수를 작성할 때) From 391bd1408c53d3c15997a00b2d923290a53452ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Wed, 20 Mar 2024 01:02:53 +0900 Subject: [PATCH 11/30] Update sections/Functions.md Co-authored-by: Park DongHa --- sections/Functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index 96b3f9f..5f0c975 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -35,7 +35,7 @@ * [F.19: "전달(forward)" 매개변수는 `TP&&`타입과 `std::forward`로만 전달하라](#Rf-forward) * [F.20: "출력(out)"에는 매개변수보다는 값을 반환하는 방법을 선호하라](#Rf-out) * [F.21: "출력"값 여러 개를 반환할 때는 튜플이나 구조체를 선호하라](#Rf-out-multi) -* [F.60: "인자가 없을 경우"를 허용한다면 `T&`보다는 `T*`를 선호하라](#Rf-ptr-ref) +* [F.60: "인자가 없을 경우(no argument)"를 허용한다면 `T&`보다는 `T*`를 선호하라](#Rf-ptr-ref) 매개변수 전달 의미구조(parameter passing semantic) 규칙: From d1428cfada8958aa9d27c14f9f71baac43253a42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Wed, 20 Mar 2024 01:28:13 +0900 Subject: [PATCH 12/30] Update sections/Functions.md Co-authored-by: Park DongHa --- sections/Functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index 5f0c975..e1c904f 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -705,7 +705,7 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt ##### Example -일반적으로 모든 정적 제어 흐름 경로에서 전체 매개변수(또는 인자 묶음(pack), 또는 `...` 사용)를 정확히 한 번 전달합니다: +일반적으로 모든 정적 제어 흐름 경로에서 전체 매개변수(또는 `...`을 사용하는 인자묶음(parameter pack))를 정확히 한 번 전달합니다: ```c++ template From 6b422f231df96355cedb8ac924163a00fd55dcc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Wed, 20 Mar 2024 01:28:25 +0900 Subject: [PATCH 13/30] Update sections/Functions.md Co-authored-by: Park DongHa --- sections/Functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index e1c904f..53698aa 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -944,7 +944,7 @@ C++ 17에서는 다수의 변수들을 선언과 동시에 초기화 할 수 있 * 출력 목적의 매개변수는 반환값으로 대체되어야 한다. 출력 매개변수는 함수(멤버함수 포함)에서 값을 변경하는 `const`가 아닌 매개변수를 의미한다. * 가능하다면 `pair` 또는 `tuple` 반환 유형은 `struct`로 대체되어야 한다. 변형 템플릿에서는 `tuple`을 사용할 수 밖에 없다. -### F.60: "인자가 없을 경우"를 허용한다면 `T&`보다는 `T*`를 선호하라 +### F.60: "인자가 없을 경우(no argument)"를 허용한다면 `T&`보다는 `T*`를 선호하라 ##### Reason From 26527c03ffacb8a033d088dd099cd2f716b6c4f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Wed, 20 Mar 2024 01:28:33 +0900 Subject: [PATCH 14/30] Update sections/Functions.md Co-authored-by: Park DongHa --- sections/Functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index 53698aa..a663231 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -1572,7 +1572,7 @@ Guaranteed copy elision이 적용되면 `std::move`를 반환 구문에 사용 반환 구문을 검사하는 도구에 의해서 검사되어야 한다. -### F.49: `return const T`는 사용하지 말아라 +### F.49: `const T`는 함수의 반환 타입으로 사용하지 말아라 ##### Reason From 9ffa1958c72d488d5f70dd2f7030a7d73a1f6769 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Mon, 1 Apr 2024 08:47:06 +0900 Subject: [PATCH 15/30] Update sections/Functions.md Co-authored-by: Chris Ohk --- sections/Functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index a663231..571c033 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -616,7 +616,7 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt ##### Note -일부 사용자 정의 및 표준 라이브러리 타입은 `span`나 반복자와 같이 [복사 비용이 저렴](#Rf-in)하고 값으로 전달될 수 있지만, 변경 가능한(in-out) 참조 의미론(semantics)을 가지고 있다: +일부 사용자 정의 및 표준 라이브러리 타입은 `span`나 반복자처럼 [복사 비용이 저렴](#Rf-in)하고 값으로 전달될 수 있지만, 변경 가능한(in-out) 참조 의미론(semantics)을 가지고 있다: ```c++ void increment_all(span a) From 339e07ea9c81e0e81304999e9aa33f7dfb582e00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Mon, 1 Apr 2024 08:47:52 +0900 Subject: [PATCH 16/30] Update sections/Functions.md Co-authored-by: Chris Ohk --- sections/Functions.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sections/Functions.md b/sections/Functions.md index 571c033..1235745 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -621,10 +621,9 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt ```c++ void increment_all(span a) { - for (auto&& e : a) - ++e; + for (auto&& e : a) + ++e; } -``` ##### Note From 44ee502fbb72fbf3c749e3f7e3f13d4b63a2ca82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Mon, 1 Apr 2024 08:55:05 +0900 Subject: [PATCH 17/30] Update sections/Functions.md Co-authored-by: Chris Ohk --- sections/Functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index 1235745..901c3c6 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -704,7 +704,7 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt ##### Example -일반적으로 모든 정적 제어 흐름 경로에서 전체 매개변수(또는 `...`을 사용하는 인자묶음(parameter pack))를 정확히 한 번 전달합니다: +일반적으로 모든 정적 제어 흐름 경로에서 전체 매개변수(또는 `...`을 사용하는 인자묶음(parameter pack))를 정확히 한 번 전달한다: ```c++ template From 2a79402e98759bba64d9f2ebeb2b0a1f45252578 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Mon, 1 Apr 2024 08:55:37 +0900 Subject: [PATCH 18/30] Update sections/Functions.md Co-authored-by: Chris Ohk --- sections/Functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index 901c3c6..2d49196 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -758,7 +758,7 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt ##### Exceptions -* 상속 계층구조에 속한 타입처럼 값 타입이 아닌 경우, 개체를 `unique_ptr` 혹은 `shared_ptr`로 반환하라 +* 상속 계층 구조에 속한 타입처럼 값 타입이 아닌 경우, 개체를 `unique_ptr` 혹은 `shared_ptr`로 반환하라. * 많약 값의 이동 비용이 크다면 (`array` 같은 경우), 자유 저장소에 할당하고 그 핸들을 (`unique_ptr`와 같은) 반환하는 것을 고려하라. 또는 `const`가 아닌 참조(출력 매개변수)를 전달해 개체를 채워넣도록 하라 * 최대 크기(capacity)를 가진 개체(예를 들어 `std::string`, `std::vector`)를 여러 함수 호출과정에서 재사용하고자 한다면, [입출력 매개변수로 참조를 전달하라](#Rf-out-multi). From 454434ce6659e956ecd79ebdad01f8aea7bca09b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Mon, 1 Apr 2024 08:59:00 +0900 Subject: [PATCH 19/30] Update sections/Functions.md Co-authored-by: Chris Ohk --- sections/Functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index 2d49196..027be10 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -909,7 +909,7 @@ C++ 17에서는 다수의 변수들을 선언과 동시에 초기화 할 수 있 추상화가 아닌 독립적인 존재들(independent entities)을 표현할 때는 `pair`와 `tuple`은 필요 이상으로 범용적(overly-generic)일 수 있다. -다른 옵션은 `pair`와 `tuple`이 아닌 `optional` 또는 `expected`를 사용하는 것입니다. 적절하게 사용될 때 이러한 타입은 `pair` 또는 `pair`보다 멤버들의 의도에 대한 더 많은 정보를 전달한다. +다른 옵션은 `pair`와 `tuple`이 아닌 `optional` 또는 `expected`를 사용하는 것이다. 적절하게 사용될 때 이러한 타입은 `pair` 또는 `pair`보다 멤버들의 의도에 대한 더 많은 정보를 전달한다. ##### Note From 37c0ef42f0ec7dd5381200cbbf269564f09603d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Mon, 1 Apr 2024 08:59:10 +0900 Subject: [PATCH 20/30] Update sections/Functions.md Co-authored-by: Chris Ohk --- sections/Functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index 027be10..ab831be 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -913,7 +913,7 @@ C++ 17에서는 다수의 변수들을 선언과 동시에 초기화 할 수 있 ##### Note -반환할 개체가 복사 비용이 많이 드는 로컬 변수에서 초기화되는 경우 명시적인 `move`가 복사를 피하는 데 도움이 될 수 있다: +반환할 개체가 복사 비용이 많이 드는 지역 변수에서 초기화되는 경우 명시적인 `move`가 복사를 피하는 데 도움이 될 수 있다: ```c++ pair f(const string& input) From 489842a4b9ce678dc385e4895309f49f008b92c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Mon, 1 Apr 2024 08:59:36 +0900 Subject: [PATCH 21/30] Update sections/Functions.md Co-authored-by: Chris Ohk --- sections/Functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index ab831be..05faa0c 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -967,7 +967,7 @@ C++ 17에서는 다수의 변수들을 선언과 동시에 초기화 할 수 있 ##### Note -가능하기는 하지만, C++에서 `nullptr`인 개체를 생성하는 것은 정상적(valid)이지 않다(예를 들어, `T* p = nullptr; T& r = (T&)*p;`). 그런 오류는 굉장히 드물다(very uncommon). +가능하기는 하지만, C++에서 `nullptr`인 개체를 생성하는 것은 정상적(valid)이지 않다 (예를 들어, `T* p = nullptr; T& r = (T&)*p;`). 그런 오류는 굉장히 드물다(very uncommon). ##### Note From f8e954135f433a5ec6622d8557f027597c3ef368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Mon, 1 Apr 2024 08:59:44 +0900 Subject: [PATCH 22/30] Update sections/Functions.md Co-authored-by: Chris Ohk --- sections/Functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index 05faa0c..3a85992 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -1575,7 +1575,7 @@ Guaranteed copy elision이 적용되면 `std::move`를 반환 구문에 사용 ##### Reason -`const` 값을 반환하는 것은 추천하지 않는다. 오래된 조언들은 무의미하다; 의미도 없고 이동 의미구조를 방해한다. +`const` 값을 반환하는 것은 추천하지 않는다. 오래된 조언들은 무의미하다; 의미도 없고 이동 의미 구조를 방해한다. ##### Example From 24a0edbca199fec79a44199becaa04da2b7b6076 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Mon, 1 Apr 2024 08:59:51 +0900 Subject: [PATCH 23/30] Update sections/Functions.md Co-authored-by: Chris Ohk --- sections/Functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index 3a85992..b020196 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -1592,7 +1592,7 @@ Guaranteed copy elision이 적용되면 `std::move`를 반환 구문에 사용 ``` 반환 값에 `const`를 사용하는 것은 임시 변수에 대한 (굉장히 드문) 우발적 접근을 막기 위한 것이다. -전달 인자에 `const`가 사용되면 (매우 자주 발생하는) 이동 의미구조를 막는다. +전달 인자에 `const`가 사용되면 (매우 자주 발생하는) 이동 의미 구조를 막는다. ##### See also From 7c643f064eedb0c470d2faa5468977ff6cefe81d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Mon, 1 Apr 2024 22:51:50 +0900 Subject: [PATCH 24/30] Update Functions.md --- sections/Functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index b020196..90bdbb7 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -686,7 +686,7 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt ##### Exception -"will-move-from" 매개 변수가 `shared_ptr`이면 [R.34](./References.md/#Rr-sharedptrparam-owner)를 따르고 `shared_ptr`을 값으로 전달한다. +"넘겨주는(will-move-from)" 매개 변수가 `shared_ptr`이면 [R.34](./References.md/#Rr-sharedptrparam-owner)를 따르고 `shared_ptr`을 값으로 전달한다. ##### Enforcement From 7fa87291a109fd129952bdaaf015e4edc9c8e711 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Sun, 7 Apr 2024 15:10:00 +0900 Subject: [PATCH 25/30] Update sections/Functions.md Co-authored-by: Park DongHa --- sections/Functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index 90bdbb7..2fdcbe1 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -716,7 +716,7 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt ##### Example -때로는 모든 정적 제어 흐름 경로에서 복합 매개 변수의 각 하위 개체를 한 번씩 전달할 수 있습니다: +때로는 모든 정적 제어 흐름 경로에서 복합 매개 변수의 각 하위 개체를 한 번씩 전달할 수 있다: ```c++ template From 36c6118bae450e06637e7fe28d023c790e80ff76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Sun, 7 Apr 2024 15:10:26 +0900 Subject: [PATCH 26/30] Update sections/Functions.md Co-authored-by: Chris Ohk --- sections/Functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index 2fdcbe1..2eae3eb 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -759,7 +759,7 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt ##### Exceptions * 상속 계층 구조에 속한 타입처럼 값 타입이 아닌 경우, 개체를 `unique_ptr` 혹은 `shared_ptr`로 반환하라. -* 많약 값의 이동 비용이 크다면 (`array` 같은 경우), 자유 저장소에 할당하고 그 핸들을 (`unique_ptr`와 같은) 반환하는 것을 고려하라. 또는 `const`가 아닌 참조(출력 매개변수)를 전달해 개체를 채워넣도록 하라 +* 만약 값의 이동 비용이 크다면 (`array` 같은 경우), 자유 저장소에 할당하고 그 핸들을 (`unique_ptr`와 같은) 반환하는 것을 고려하라. 또는 `const`가 아닌 참조(출력 매개변수)를 전달해 개체를 채워넣도록 하라. * 최대 크기(capacity)를 가진 개체(예를 들어 `std::string`, `std::vector`)를 여러 함수 호출과정에서 재사용하고자 한다면, [입출력 매개변수로 참조를 전달하라](#Rf-out-multi). ##### Example From 559c29b5c8c92af1ae43ef1e8e2847577e801ec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Sun, 7 Apr 2024 15:16:21 +0900 Subject: [PATCH 27/30] Update sections/Functions.md Co-authored-by: Park DongHa --- sections/Functions.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sections/Functions.md b/sections/Functions.md index 2eae3eb..9d0fcf9 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -732,6 +732,8 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt * 모든 정적 경로에 대해 단 한번 `std::forward`하는 경우를 제외하고 `TP&&` 매개변수를 받는 함수를 지적한다. (`TP`는 템플릿 인자의 이름이다) 또는 `std::forward`을 한 번 이상 수행하지만 정적 경로마다 정확히 한 번씩 다른 데이터 멤버로 자격을 부여한다. +> * Flag a function that takes a TP&& parameter (where TP is a template type parameter name) and does anything with it other than std::forwarding it exactly once on every static path, or std::forwarding it more than once but qualified with a different data member exactly once on every static path. + ### F.20: "출력(out)"에는 매개변수보다는 값을 반환하는 방법을 선호하라 ##### Reason From 74954b8886491b428c40f8fe6d2c651024287090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Sun, 7 Apr 2024 15:22:11 +0900 Subject: [PATCH 28/30] Update sections/Functions.md Co-authored-by: Chris Ohk --- sections/Functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index 9d0fcf9..8c031a4 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -762,7 +762,7 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt * 상속 계층 구조에 속한 타입처럼 값 타입이 아닌 경우, 개체를 `unique_ptr` 혹은 `shared_ptr`로 반환하라. * 만약 값의 이동 비용이 크다면 (`array` 같은 경우), 자유 저장소에 할당하고 그 핸들을 (`unique_ptr`와 같은) 반환하는 것을 고려하라. 또는 `const`가 아닌 참조(출력 매개변수)를 전달해 개체를 채워넣도록 하라. -* 최대 크기(capacity)를 가진 개체(예를 들어 `std::string`, `std::vector`)를 여러 함수 호출과정에서 재사용하고자 한다면, [입출력 매개변수로 참조를 전달하라](#Rf-out-multi). +* 최대 크기(capacity)를 가진 개체(예를 들어 `std::string`, `std::vector`)를 여러 함수 호출 과정에서 재사용하고자 한다면, [입출력 매개변수로 참조를 전달하라](#Rf-out-multi). ##### Example From 90a9d112a31e3ac62f3353c367b8af8c5f9a5b1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Sun, 7 Apr 2024 15:22:35 +0900 Subject: [PATCH 29/30] Update sections/Functions.md Co-authored-by: Park DongHa --- sections/Functions.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index 8c031a4..1e63e48 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -808,7 +808,11 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt ##### Reason -반환 값은 그 자체로 문서가 필요하지 않고 "출력 전용"으로 사용된다. C++ 에서는 다수의 값을 반환할때는 튜플과 유사한 유형(`struct`, `array`, `tuple` 등)를 쓴다는 것을 기억하라, 호출한 지점에서 구조화된 바인딩(structured bindings)(C++17)을 추가로 편리하게 사용할 수 있다. 반환 값에 의미구조가 있다면 별도의 `struct` 타입을 사용하라. 그렇지 않다면 일반적인 코드에서는 (이름 없는) `tuple`이 유용하다. +반환 값은 그 자체로 문서가 필요하지 않고 "출력 전용"으로 사용된다. +C++ 에서는 다수의 값을 반환할때는 튜플과 유사한 타입(`struct`, `array`, `tuple` 등)를 쓴다는 것을 기억하라, +호출한 지점에서 구조화된 바인딩(structured bindings)(C++17)을 추가로 편리하게 사용할 수 있다. +반환 값에 의미구조가 있다면 별도의 `struct` 타입을 사용하라. +그렇지 않다면 일반적인 코드에서는 (이름 없는) `tuple`이 유용하다. ##### Example From 4f75cc59dc156f005339d9f5de6eb81ea884a36b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eddy=20/=20=EB=B3=B4=EB=A6=AC=EB=82=A8=ED=8E=B8=20?= =?UTF-8?q?=EA=B9=80=20=EC=A3=BC=EB=B6=80?= <46366895+jabdong4ny@users.noreply.github.com> Date: Sun, 7 Apr 2024 15:22:57 +0900 Subject: [PATCH 30/30] Update sections/Functions.md Co-authored-by: Park DongHa --- sections/Functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sections/Functions.md b/sections/Functions.md index 1e63e48..70b0616 100644 --- a/sections/Functions.md +++ b/sections/Functions.md @@ -851,7 +851,7 @@ C++ 17에서는 다수의 변수들을 선언과 동시에 초기화 할 수 있 do_something_with(iter); ``` -모던 C++에서는 의미 있는 이름을 가진 `struct`가 더 일반적입니다. 예를 들어 `ranges::min_max_result`, `from_chars_result` 등을 참조. +모던 C++에서는 의미 있는 이름을 가진 `struct`가 더 일반적이다. 예를 들어 `ranges::min_max_result`, `from_chars_result` 등을 참조하라. ##### Exception