Skip to content

Commit 90c8d0e

Browse files
authoredMay 7, 2024··
Merge pull request #168 from jabdong4ny/master
F.call: 매개변수 전달(Parameter passing) 번역 최신화
2 parents 249a8ea + 4f75cc5 commit 90c8d0e

File tree

1 file changed

+192
-111
lines changed

1 file changed

+192
-111
lines changed
 

‎sections/Functions.md

+192-111
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
* [F.19: "전달(forward)" 매개변수는 `TP&&`타입과 `std::forward`로만 전달하라](#Rf-forward)
3636
* [F.20: "출력(out)"에는 매개변수보다는 값을 반환하는 방법을 선호하라](#Rf-out)
3737
* [F.21: "출력"값 여러 개를 반환할 때는 튜플이나 구조체를 선호하라](#Rf-out-multi)
38+
* [F.60: "인자가 없을 경우(no argument)"를 허용한다면 `T&`보다는 `T*`를 선호하라](#Rf-ptr-ref)
3839

3940
매개변수 전달 의미구조(parameter passing semantic) 규칙:
4041

@@ -44,7 +45,6 @@
4445
* [F.25: C 스타일 문자열에는 `zstring` 혹은 `not_null<zstring>`을 사용하라](#Rf-zstring)
4546
* [F.26: 포인터가 필요한 곳에 소유권을 전달할 때는 `unique_ptr<T>`를 사용하라](#Rf-unique_ptr)
4647
* [F.27: 소유권을 공유할 때는 `shared_ptr<T>`를 사용하라](#Rf-shared_ptr)
47-
* [F.60: "인자가 없을 경우"를 허용한다면 `T&`보다는 `T*`를 선호하라](#Rf-ptr-ref)
4848

4949
<a name="Rf-value-return"></a>값 반환 의미구조 규칙:
5050

@@ -55,6 +55,7 @@
5555
* [F.46: `main()``int`를 반환해야 한다](#Rf-main)
5656
* [F.47: 대입 연산자는 `T&`를 반환하라](#Rf-assignment-op)
5757
* [F.48: `return std::move(local)`은 사용하지 말아라](#Rf-return-move-local)
58+
* [F.49: `const T``return`에 사용하지 말아라](#Rf-return-const)
5859

5960
기타 함수 규칙:
6061

@@ -469,7 +470,7 @@ C++14 에서는 이와 같이 작성할 수 있다. C++ 11 환경이라면, `fac
469470
470471
##### See also
471472
472-
* [전달인자가 없는 경우가 허용된다면 `T&`보다는 `T*`를 선호하라](#Rf-ptr-ref)
473+
* [전달인자가 없는 경우가 허용된다면 `T&`보다는 `T*`를 선호하라](./Expr.md/#Rf-ptr-ref)
473474
* [스마트 포인터 규칙 요약](./Resource.md#Rr-summary-smartptrs)
474475
475476
##### Enforcement
@@ -539,6 +540,12 @@ C++14 에서는 이와 같이 작성할 수 있다. C++ 11 환경이라면, `fac
539540
540541
필요한 경우에만 고급 기술을 사용하고, 주석으로 문서화하라.
541542
543+
문자열 전달은 [String](./SL.md#SS-string) 참고.
544+
545+
##### Exception
546+
547+
`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)을 참고하라.
548+
542549
### <a name="Rf-in"></a>F.16: "입력(in)" 매개변수는 복사 비용이 적게 드는 타입의 경우 값으로 전달하고, 그 외에는 상수 참조형으로 전달하라
543550
544551
##### Reason
@@ -578,39 +585,22 @@ C++14 에서는 이와 같이 작성할 수 있다. C++ 11 환경이라면, `fac
578585
void sink(unique_ptr<widget>); // input only, and moves ownership of the widget
579586
```
580587
581-
아래와 같은 "난해한 기술"은 지양하라:
582-
583-
* "효율적이라서" 인자를 `T&&`로 전달한다. `&&`로 전달함으로써 발생하는 성능 향상에 대한 루머는 잘못되었고 깨지기 쉽다(속단하지 말고 [F.18](#Rf-consume)와 [F.19](#Rf-forward)를 참고하라)
584-
* 대입에서 `const T&`를 반환하거나 비슷한 연산을 수행한다 ([F.47](#Rf-assignment-op) 참고)
585-
586-
##### Example
587-
588-
`Matrix`가 이동 연산을 지원한다고 가정하자(아마도 원소들을 `std::vector`에 보관하고 있다):
589-
590-
```c++
591-
Matrix operator+(const Matrix& a, const Matrix& b)
592-
{
593-
Matrix res;
594-
// ... fill res with the sum ...
595-
return res;
596-
}
597-
598-
Matrix x = m1 + m2; // move constructor
599-
600-
y = m3 + m3; // move assignment
601-
```
588+
"효율적이라서" 인자를 `T&&`로 전달한다. `&&`로 전달함으로써 발생하는 성능 향상에 대한 루머는 잘못되었고 깨지기 쉽다(속단하지 말고 [F.18](#Rf-consume)와 [F.19](#Rf-forward)를 참고하라)
602589
603590
##### Notes
604591
605-
반환 값 최적화는 대입에 대해서는 동작하지 않지만, 이동 대입의 경우에는 적용된다.
606592
참조는 언어 규칙에 의해 유효한 개체를 가리킨다고 가정하기 때문에, null 참조는 발생하지 않는다.
607593
optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::optional` 혹은 "값이 없음"을 의미하는 특별한 값을 사용하라.
608594
609595
##### Enforcement
610596
611-
* (쉬움) (기본 사항) 인자의 크기가 `4 * sizeof(int)` 보다 크면 경고한다. `const` 참조를 전달하도록 제안한다
612-
* (쉬움) (기본 사항) `const` 참조로 전달되는 인자의 크기가 `3 * sizeof(int)`보다 작다면 경고한다. 값 전달을 대신 사용하도록 제안한다
613-
* (쉬움) (기본 사항) `const` 참조 매개변수가 `move`되면 경고한다
597+
* (쉬움) (기본 사항) 인자의 크기가 `2 * sizeof(void*)` 보다 크면 경고한다. 대신 `const` 참조를 전달하도록 제안한다.
598+
* (쉬움) (기본 사항) `const` 참조로 전달되는 인자의 크기가 `2 * sizeof(void*)` 이하면 경고한다. 대신 값을 전달하도록 제안한다.
599+
* (쉬움) (기본 사항) `const` 참조 매개변수가 `move`되면 경고한다.
600+
601+
##### Exception
602+
603+
`shared_ptr` 타입을 사용하여 공유 소유권을 표현하려면 함수가 전달인자를 참조하는지 여부에 따라 [R.34](./References.md/#Rr-sharedptrparam-owner) 또는 [R.36](./References.md/#Rr-sharedptrparam-const)를 참고하라.
614604
615605
### <a name="Rf-inout"></a>F.17: "입출력(in-out)" 매개변수는 비상수 참조형으로 전달하라
616606
@@ -626,6 +616,17 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt
626616

627617
##### Note
628618

619+
일부 사용자 정의 및 표준 라이브러리 타입은 `span<T>`나 반복자처럼 [복사 비용이 저렴](#Rf-in)하고 값으로 전달될 수 있지만, 변경 가능한(in-out) 참조 의미론(semantics)을 가지고 있다:
620+
621+
```c++
622+
void increment_all(span<int> a)
623+
{
624+
for (auto&& e : a)
625+
++e;
626+
}
627+
628+
##### Note
629+
629630
`T&` 인자는 정보를 전달할 수도 있지만 받아올 수도 있다.
630631
때문에 `T&`는 입출력 매개변수가 될 수 있다. 이로 인해 문제가 되거나 오류의 원인이 되기도 한다:
631632

@@ -649,7 +650,7 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt
649650
##### Enforcement
650651
651652
* (중간) (기본 사항) 함수 내에서 값을 변경하지 않는 비 `const` 참조를 경고한다
652-
* (쉬움) (기본 사항) `const` 참조 매개변수가 `move`되면 경고한다
653+
* (쉬움) (기본 사항) `const` 참조 매개변수가 `move`되면 경고한다
653654
654655
### <a name="Rf-consume"></a>F.18: "넘겨주는(will-move-from)" 매개변수는 `X&&`타입과 `std::move`로 전달하라
655656
@@ -683,6 +684,10 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt
683684
} // p gets destroyed
684685
```
685686
687+
##### Exception
688+
689+
"넘겨주는(will-move-from)" 매개 변수가 `shared_ptr`이면 [R.34](./References.md/#Rr-sharedptrparam-owner)를 따르고 `shared_ptr`을 값으로 전달한다.
690+
686691
##### Enforcement
687692
688693
* 모든 `std::move`없이 `X&&` 매개변수를 사용하면 지적한다 (이때 `X`는 템플릿 인자가 아니다)
@@ -699,18 +704,35 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt
699704
700705
##### Example
701706
707+
일반적으로 모든 정적 제어 흐름 경로에서 전체 매개변수(또는 `...`을 사용하는 인자묶음(parameter pack))를 정확히 한 번 전달한다:
708+
702709
```c++
703-
template <class F, class... Args>
704-
inline auto invoke(F f, Args&&... args) {
705-
return f(forward<Args>(args)...);
710+
template<class F, class... Args>
711+
inline decltype(auto) invoke(F&& f, Args&&... args)
712+
{
713+
return forward<F>(f)(forward<Args>(args)...);
706714
}
715+
```
716+
717+
##### Example
718+
719+
때로는 모든 정적 제어 흐름 경로에서 복합 매개 변수의 각 하위 개체를 한 번씩 전달할 수 있다:
707720

708-
??? calls ???
721+
```c++
722+
template<class PairLike>
723+
inline auto test(PairLike&& pairlike)
724+
{
725+
// ...
726+
f1(some, args, and, forward<PairLike>(pairlike).first); // forward .first
727+
f2(and, forward<PairLike>(pairlike).second, in, another, call); // forward .second
728+
}
709729
```
710730
711731
##### Enforcement
712732
713-
* 모든 정적 경로에 대해 단 한번 `std::forward`하는 경우를 제외하고 `TP&&` 매개변수를 받는 함수를 지적한다 (`TP`는 템플릿 인자의 이름이다).
733+
* 모든 정적 경로에 대해 단 한번 `std::forward`하는 경우를 제외하고 `TP&&` 매개변수를 받는 함수를 지적한다. (`TP`는 템플릿 인자의 이름이다) 또는 `std::forward`을 한 번 이상 수행하지만 정적 경로마다 정확히 한 번씩 다른 데이터 멤버로 자격을 부여한다.
734+
735+
> * 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.
714736
715737
### <a name="Rf-out"></a>F.20: "출력(out)"에는 매개변수보다는 값을 반환하는 방법을 선호하라
716738
@@ -736,28 +758,32 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt
736758

737759
(각각의 이동 비용이 크지 않은) 멤버를 많이 가진 `struct`는 전체적으로는 이동 비용이 클 수 있다.
738760

739-
`const` 값을 반환하는 것은 추천하지 않는다. 오래된 조언들은 무의미하다: 의미도 없고 이동 의미구조를 방해한다.
761+
##### Exceptions
762+
763+
* 상속 계층 구조에 속한 타입처럼 값 타입이 아닌 경우, 개체를 `unique_ptr` 혹은 `shared_ptr`로 반환하라.
764+
* 만약 값의 이동 비용이 크다면 (`array<BigTrivial>` 같은 경우), 자유 저장소에 할당하고 그 핸들을 (`unique_ptr`와 같은) 반환하는 것을 고려하라. 또는 `const`가 아닌 참조(출력 매개변수)를 전달해 개체를 채워넣도록 하라.
765+
* 최대 크기(capacity)를 가진 개체(예를 들어 `std::string`, `std::vector`)를 여러 함수 호출 과정에서 재사용하고자 한다면, [입출력 매개변수로 참조를 전달하라](#Rf-out-multi).
740766

741-
```c++
742-
const vector<int> fct(); // bad: that "const" is more trouble than it is worth
767+
##### Example
743768

744-
vector<int> g(const vector<int>& vx)
769+
`Matrix`가 이동 연산을 지원한다고 가정하자(아마도 원소들을 `std::vector`에 보관하고 있다):
770+
771+
```c++
772+
Matrix operator+(const Matrix& a, const Matrix& b)
745773
{
746-
// ...
747-
fct() = vx; // prevented by the "const"
748-
// ...
749-
return fct(); // expensive copy: move semantics suppressed by the "const"
774+
Matrix res;
775+
// ... fill res with the sum ...
776+
return res;
750777
}
751-
```
752778

753-
반환 값에 `const`를 사용하는 것은 임시 변수에 대한 (굉장히 드문) 우발적 접근을 막기 위한 것이다.
754-
전달 인자에 `const`가 사용되면 (매우 자주 발생하는) 이동 의미구조를 막는다.
779+
Matrix x = m1 + m2; // move constructor
755780

756-
##### Exceptions
781+
y = m3 + m3; // move assignment
782+
```
783+
784+
##### Notes
757785
758-
* 상속 계층구조에 속한 타입처럼 값 타입이 아닌 경우, 개체를 `unique_ptr` 혹은 `shared_ptr`로 반환하라
759-
* 많약 값의 이동 비용이 크다면 (`array<BigPOD>` 같은 경우), 자유 저장소에 할당하고 그 핸들을 (`unique_ptr`와 같은) 반환하는 것을 고려하라. 또는 `const`가 아닌 참조(출력 매개변수)를 전달해 개체를 채워넣도록 하라
760-
* 최대 크기(capacity)를 가진 개체(예를 들어 `std::string`, `std::vector`)를 여러 함수 호출과정에서 재사용하고자 한다면, [입출력 매개변수로 참조를 전달하라](#Rf-out-multi).
786+
반환 값 최적화는 대입에 대해서는 동작하지 않지만, 이동 대입의 경우에는 적용된다.
761787
762788
##### Example
763789
@@ -777,15 +803,16 @@ optional 값에 대해 알고 있다면, 포인터를 사용하거나, `std::opt
777803
##### Enforcement
778804

779805
* 큰 비용 없이 반환할 수 있으면서 값을 변경하기 전에 사용하는 비 `const` 참조 매개변수를 지적하라; 이들은 "출력" 반환 값이 적절하다.
780-
* `const` 반환 값을 지적한다. `const`를 제거하도록 권한다
781806

782807
### <a name="Rf-out-multi"></a>F.21: "출력"값 여러 개를 반환할 때는 튜플이나 구조체를 선호하라
783808

784809
##### Reason
785810

786811
반환 값은 그 자체로 문서가 필요하지 않고 "출력 전용"으로 사용된다.
787-
C++ 에서는 다수의 값을 반환할때는 `tuple`(`pair`를 포함해)를 쓴다는 것을 기억하라, 호출한 지점에서 `tie`를 사용해 받을 것이다.
788-
반환 값에 의미구조가 있다면 별도의 struct 타입을 사용하라. 그렇지 않다면 일반적인 코드에서는 (이름 없는) `tuple`이 유용하다.
812+
C++ 에서는 다수의 값을 반환할때는 튜플과 유사한 타입(`struct`, `array`, `tuple` 등)를 쓴다는 것을 기억하라,
813+
호출한 지점에서 구조화된 바인딩(structured bindings)(C++17)을 추가로 편리하게 사용할 수 있다.
814+
반환 값에 의미구조가 있다면 별도의 `struct` 타입을 사용하라.
815+
그렇지 않다면 일반적인 코드에서는 (이름 없는) `tuple`이 유용하다.
789816

790817
##### Example
791818

@@ -799,39 +826,33 @@ C++ 에서는 다수의 값을 반환할때는 `tuple`(`pair`를 포함해)를
799826
}
800827

801828
// GOOD: self-documenting
802-
tuple<int, string> f(const string& input)
829+
struct f_result { int status; string data; };
830+
831+
f_result f(const string& input)
803832
{
804833
// ...
805-
return make_tuple(status, something());
834+
return {status, something()};
806835
}
807836
```
808837
809-
사실, C++98의 표준 라이브러리에서는 `pair`가 개체 2개를 묶은 `tuple`과 같기 때문에 이 기능을 편리하게 사용하고 있었다.
810-
811-
예를 들어, `set<string> my_set`이 주어졌다고 가정하면:
838+
C++98의 표준 라이브러리에서는 일부 함수에서 `pair`를 반환하는 스타일을 사용했다. 예를 들어, `set<string> my_set`이 주어졌다고 가정하면:
812839
813840
```c++
814841
// C++98
815-
result = my_set.insert("Hello");
816-
if (result.second) do_something_with(result.first); // workaround
817-
```
818-
819-
C++11에서는 이렇게 작성할 수 있다, 결과값들을 이미 존재하는 지역변수에 대입한다:
820-
821-
```c++
822-
Sometype iter; // default initialize if we haven't already
823-
Someothertype success; // used these variables for some other purpose
824-
825-
tie(iter, success) = my_set.insert("Hello"); // normal return value
826-
if (success) do_something_with(iter);
842+
pair<set::iterator, bool> result = my_set.insert("Hello");
843+
if (result.second)
844+
do_something_with(result.first); // workaround
827845
```
828846

829847
C++ 17에서는 다수의 변수들을 선언과 동시에 초기화 할 수 있는 "structured bindings"을 지원한다:
830848

831849
```c++
832-
if (auto [ iter, success ] = my_set.insert("Hello"); success) do_something_with(iter);
850+
if (auto [ iter, success ] = my_set.insert("Hello"); success)
851+
do_something_with(iter);
833852
```
834853
854+
모던 C++에서는 의미 있는 이름을 가진 `struct`가 더 일반적이다. 예를 들어 `ranges::min_max_result`, `from_chars_result` 등을 참조하라.
855+
835856
##### Exception
836857
837858
때에 따라서는 개체의 상태를 변경하기 위해 함수에 개체를 전달해야 할 수도 있다.
@@ -856,16 +877,18 @@ C++ 17에서는 다수의 변수들을 선언과 동시에 초기화 할 수 있
856877
비교를 위해, 값을 반환하는 방법으로 해결한다면 아래와 같이 작성하게 될 것이다:
857878

858879
```c++
859-
pair<istream&, string> get_string(istream& is); // not recommended
880+
struct get_string_result { istream& in; string s; };
881+
882+
get_string_result get_string(istream& in) // not recommended
860883
{
861884
string s;
862-
is >> s;
863-
return {is, s};
885+
in >> s;
886+
return { in, move(s) };
864887
}
865888

866-
for (auto p = get_string(cin); p.first; ) {
867-
// do something with p.second
868-
}
889+
for (auto [in, s] = get_string(cin); in; s = get_string(in).s) {
890+
// do something with string
891+
}
869892
```
870893
871894
생각보다 아름답지 않고 성능에도 좋지 않다.
@@ -892,11 +915,73 @@ C++ 17에서는 다수의 변수들을 선언과 동시에 초기화 할 수 있
892915

893916
추상화가 아닌 독립적인 존재들(independent entities)을 표현할 때는 `pair``tuple`은 필요 이상으로 범용적(overly-generic)일 수 있다.
894917

895-
다른 예로는, `tuple`대신 특정 타입과 비슷한 `variant<T, error_code>`를 사용하라.
918+
다른 옵션은 `pair``tuple`이 아닌 `optional<T>` 또는 `expected<T, error_code>`를 사용하는 것이다. 적절하게 사용될 때 이러한 타입은 `pair<T, bool>` 또는 `pair<T, error_code>`보다 멤버들의 의도에 대한 더 많은 정보를 전달한다.
919+
920+
##### Note
921+
922+
반환할 개체가 복사 비용이 많이 드는 지역 변수에서 초기화되는 경우 명시적인 `move`가 복사를 피하는 데 도움이 될 수 있다:
923+
924+
```c++
925+
pair<LargeObject, LargeObject> f(const string& input)
926+
{
927+
LargeObject large1 = g(input);
928+
LargeObject large2 = h(input);
929+
// ...
930+
return { move(large1), move(large2) }; // no copies
931+
}
932+
```
933+
934+
다른 방법으로는,
935+
936+
```c++
937+
pair<LargeObject, LargeObject> f(const string& input)
938+
{
939+
// ...
940+
return { g(input), h(input) }; // no copies, no moves
941+
}
942+
```
943+
##### Note
944+
945+
이는 [ES.56](#Res-move)`return move(...)` 안티 패턴과 다르다.
896946

897947
##### Enforcement
898948

899949
* 출력 목적의 매개변수는 반환값으로 대체되어야 한다. 출력 매개변수는 함수(멤버함수 포함)에서 값을 변경하는 `const`가 아닌 매개변수를 의미한다.
950+
* 가능하다면 `pair` 또는 `tuple` 반환 유형은 `struct`로 대체되어야 한다. 변형 템플릿에서는 `tuple`을 사용할 수 밖에 없다.
951+
952+
### <a name="Rf-ptr-ref"></a>F.60: "인자가 없을 경우(no argument)"를 허용한다면 `T&`보다는 `T*`를 선호하라
953+
954+
##### Reason
955+
956+
포인터(`T*`)는 `nullptr`일 수 있지만, 참조(`T&`)는 그렇지 않다.
957+
경우에 따라서는 "개체 없음"을 표시하기 위해 `nullptr`를 사용하는 것이 유용할 수 있다. 그렇지 않다면, 참조가 더 간단하고 좋은 코드로 이어질 것이다.
958+
959+
##### Example
960+
961+
```c++
962+
string zstring_to_string(zstring p) // zstring is a char*; that is a C-style string
963+
{
964+
if (!p) return string{}; // p might be nullptr; remember to check
965+
return string{p};
966+
}
967+
968+
void print(const vector<int>& r)
969+
{
970+
// r refers to a vector<int>; no check needed
971+
}
972+
```
973+
974+
##### Note
975+
976+
가능하기는 하지만, C++에서 `nullptr`인 개체를 생성하는 것은 정상적(valid)이지 않다 (예를 들어, `T* p = nullptr; T& r = (T&)*p;`). 그런 오류는 굉장히 드물다(very uncommon).
977+
978+
##### Note
979+
980+
포인터 표기법을 선호한다면 (`.`보다는 `->` 혹은 `*`가 좋다면), `not_null<T*>`이 `T&`처럼 사용될 수 있다.
981+
982+
##### Enforcement
983+
984+
???
900985
901986
### <a name="Rf-ptr"></a>F.22: T* 혹은 owner<T*>를 단일 개체를 지정하기 위해 사용하라
902987
@@ -1159,41 +1244,6 @@ Consider:
11591244
11601245
(실행 불가) 제대로 탐지하기엔 너무 복잡한 패턴을 띄고 있다.
11611246
1162-
### <a name="Rf-ptr-ref"></a>F.60: "인자가 없을 경우"를 허용한다면 `T&`보다는 `T*`를 선호하라
1163-
1164-
##### Reason
1165-
1166-
포인터(`T*`)는 `nullptr`일 수 있지만, 참조(`T&`)는 그렇지 않다.
1167-
경우에 따라서는 "개체 없음"을 표시하기 위해 `nullptr`를 사용하는 것이 유용할 수 있다. 그렇지 않다면, 참조가 더 간단하고 좋은 코드로 이어질 것이다.
1168-
1169-
##### Example
1170-
1171-
```c++
1172-
string zstring_to_string(zstring p) // zstring is a char*; that is a C-style string
1173-
{
1174-
if (!p) return string{}; // p might be nullptr; remember to check
1175-
return string{p};
1176-
}
1177-
1178-
void print(const vector<int>& r)
1179-
{
1180-
// r refers to a vector<int>; no check needed
1181-
}
1182-
```
1183-
1184-
##### Note
1185-
1186-
1187-
가능하기는 하지만, C++에서 `nullptr`인 개체를 생성하는 것은 정상적(valid)이지 않다(예를 들어, `T* p = nullptr; T& r = (T&)*p;`). 그런 오류는 굉장히 드물다(very uncommon).
1188-
1189-
##### Note
1190-
1191-
포인터 표기법을 선호한다면 (`.`보다는 `->` 혹은 `*`가 좋다면), `not_null<T*>``T&`처럼 사용될 수 있다.
1192-
1193-
##### Enforcement
1194-
1195-
???
1196-
11971247
### <a name="Rf-return-ptr"></a>F.42: 위치를 나타내는 경우에만 `T*`를 반환하라
11981248
11991249
##### Reason
@@ -1527,6 +1577,37 @@ Guaranteed copy elision이 적용되면 `std::move`를 반환 구문에 사용
15271577

15281578
반환 구문을 검사하는 도구에 의해서 검사되어야 한다.
15291579

1580+
### <a name="Rf-return-const"></a>F.49: `const T`는 함수의 반환 타입으로 사용하지 말아라
1581+
1582+
##### Reason
1583+
1584+
`const` 값을 반환하는 것은 추천하지 않는다. 오래된 조언들은 무의미하다; 의미도 없고 이동 의미 구조를 방해한다.
1585+
1586+
##### Example
1587+
1588+
```c++
1589+
const vector<int> fct(); // bad: that "const" is more trouble than it is worth
1590+
1591+
vector<int> g(const vector<int>& vx)
1592+
{
1593+
// ...
1594+
fct() = vx; // prevented by the "const"
1595+
// ...
1596+
return fct(); // expensive copy: move semantics suppressed by the "const"
1597+
}
1598+
```
1599+
1600+
반환 값에 `const`를 사용하는 것은 임시 변수에 대한 (굉장히 드문) 우발적 접근을 막기 위한 것이다.
1601+
전달 인자에 `const`가 사용되면 (매우 자주 발생하는) 이동 의미 구조를 막는다.
1602+
1603+
##### See also
1604+
1605+
[F.20: 출력 값 "out"에 대한 일반 항목](#Rf-out)
1606+
1607+
##### Enforcement
1608+
1609+
* `const` 값을 반환에 사용하면 지적한다. `const`를 제거하도록 권한다.
1610+
15301611
### <a name="Rf-capture-vs-overload"></a>F.50: 함수를 쓸 수 없을 때는 람다를 사용하라(지역 변수를 캡쳐하거나 지역 함수를 작성할 때)
15311612
15321613
##### Reason

0 commit comments

Comments
 (0)
Please sign in to comment.