2012-11-20 3 views
3

가능한 중복 :
template pass by value or const reference or…?함수를 매개 변수로 전달하는 것이 좋습니다 : 복사, 참조, const 참조?

는 A 매개 변수로 함수를 복용하는 기능에 대해 다음에 좋은 방법은 무엇

:

template<class Function> void test1(Function f); 
template<class Function> void test2(Function& f); 
template<class Function> void test3(const Function& f); 

전달 기능을 할 수있는가 functor, std :: function, 함수 포인터 또는 lambda 함수가 될 수 있습니다.

+0

@MooingDuck :이 질문은 다소 다른 질문이라고 생각합니다. – NPE

+0

@NPE : 더 일반적인 질문이지만 대답은이 질문에 대한 답입니다. –

+0

@MooingDuck : 내가 언급 한 질문에 대한 대답에 동의하지 않습니다! 나는 대답으로 설명 할 것이다. –

답변

6

사용 보편적 참조 당신은 그것에 대해 생각하지 않아도됩니다 :

인수는 인수의 유형을 추론 기능 템플릿에 전달
template<class Function> void test(Function&& f); 
4

, 그것은 어떻게 인수해야하는 등 흥미로운 질문입니다 통과 되라. 인수 사용의 정확한 특성은 중요하지 않습니다. 인수가 함수 오브젝트, 반복자, 값 등으로 사용되는지 여부는 응답에 상당히 관련이 없습니다. 네 가지 옵션이 있습니다

  1. template <typename T> void f(T&& a)
  2. template <typename T> void f(T& a)
  3. template <typename T> void f(T const& a)
  4. template <typename T> void f(T a)

그것은 함수 템플릿이 실제로 무엇을하는지에 관해서는 조금 문제 : 모든 f()는 인수와 함께 않는 경우 a은 다른 기능으로 전달하기 위해 범용 참조로 전달하려고합니다. 호출 된 함수는 부적절한 옵션을 거부하여 세부 정보를 정렬합니다. 물론, 일반적으로 유용하지만 포워딩 기능은 다소 지루합니다. 이 참조하는 경우 우리가 모르는 어떤 유형의 보편적 인 기준 결과에 의해

  1. 패스 나 :

    실제로 객체 뭔가, 우리가 일반적으로 즉시 옵션 두 가지를 폐기 할 수 않습니다 f()하는 경우 가치. 이는 값 또는 유사 참조처럼 작동하는 형식을 전달하는 것 이외에는 아무 쓸모가 없습니다. 함수가 실제로하는 일을 지정하는 것은 문제가되는 춤일 것입니다.

  2. 패스 : T const&은 우리에게 많은 도움이되지 않습니다. 우리는 통제 할 수없는 수명과 그로부터 이동할 수없고 가져올 수없는 객체에 대한 참조를 얻었습니다.

개체 자체가 수정되면 참조가 아닌 const 참조로 개체를 전달하는 것이 유용 할 수 있습니다. 이는 분명히 기능 계약의 중요한 부분이며, 취해진 기능 의뢰인이 무시할 수없는 부과 된 설계 선택 사항입니다.

선호하는 방법은 값으로 인수를 취하는 것입니다. 일반적으로 함수의 동작을 훨씬 쉽게 정의 할 수 있으며 실제로 유형이 값 또는 참조 의미를 따라야하는지 여부를 선택할 수 있습니다. 가치로 전달 된 것이 단지 목적의 대상이 가치로 전달된다는 것을 의미하지는 않습니다.특히 함수 객체의 경우 표준 C++ 라이브러리는 값 유형 참조 의미를 제공하는 일반 어댑터 ​​(std::ref())를 제공합니다.

물론 인터페이스 디자인은 미묘하며 옵션 중 하나가 보증되는 경우가 있습니다. 그러나 일반적으로 생각하면 매우 간단합니다.

  1. 전달 기능은 범용 참조를 사용합니다.
  2. 인수로 값을 사용하는 함수는 값을 사용합니다.

... 물론 이러한 규칙은 형식이 추론 된 함수 템플릿에 대한 인수에만 적용됩니다.

+0

1.'T'가'&'와'&&'에 대해'operator()'오버로드가있는 펑터 인 경우 쓸모 없지 않을 수 있습니다. – ildjarn

+0

@ildjarn : 나는 함수 객체의 인터페이스에 대해 말하는 것이 아니라 추론 된 인자가 함수 템플릿에 의해 어떻게 취해지는지를 말하고 있습니다. –

+0

나는 따라하지 않는다 ... 내가 말하는 것은'T'와'a()'와'T &&'와'std :: forward (a)()'는 서로 다른 행동을 할 수 있다는 것이다. 잠재적 인 차이는 나를 '쓸데없는 것'으로 치지 않습니다. – ildjarn

관련 문제