2014-12-17 1 views
2

가변 인수 템플릿 인수가있는 std::forward 사용법의 두 가지 변형이 있습니다.std :: forward <Args> 또는 std :: forward <Args...>?

template <typename... Args> 
void foo(Args&&... arga) 
{ 
    bar(std::forward<Args>(args)...);  // variant 1 
    bar(std::forward<Args...>(args)...); // variant 2 

    // EDIT the above is a fixed version, the initial incorrect version was 
    // bar(std::forward<Args>(args...));  // variant 1 
    // bar(std::forward<Args...>(args...)); // variant 2 

} 

g ++과 clang의 두 변종을 모두 사용해 보았으며, 둘 다 똑같이 잘 작동하는 것처럼 보입니다. -Wall -Wextra -Wpedantic으로 경고가 생성되지 않았습니다.

두 변종이 모두 정확합니까? 그렇지 않다면 왜 안 되겠습니까? 표준이 그것에 대해 무엇을 말해야합니까?

+0

업데이트 된 질문이 많이 변경되지 않아도 변형 2는 두 개 이상의 매개 변수와 함께 작동하지 않습니다. 실제로 코드를 어떻게 테스트 했습니까? 실제로 작동하는지 여부를 확인하려면 [매개 변수의 모든 관련 조합으로 인스턴스화] (http://coliru.stacked-crooked.com/a/a2695d46af54ce26)해야합니다. –

+0

@DanielFrey 분명히 적절하게 테스트되지 않았습니다. –

답변

10
bar(std::forward<Args>(args)...);  // variant 1 

올바른 내용입니다.

bar(std::forward<Args...>(args...)); // variant 2 

잘못되었습니다.

매개 변수 팩이 비어 있으면 변형 1은 유효한 bar()으로 확장되지만 변형 2는 forward에 매개 변수가 없기 때문에 변형 된 bar(std::forward<>())으로 확장됩니다.

팩에 하나의 요소가있는 경우 두 변형 모두 유효한 bar(std::forward<T>(t))으로 확장됩니다.

팩에 두 개의 요소가있는 경우 변형 1이 올바르게 적용되어 bar(std::forward<T1>(t1), std::forward<T2>(t2))으로 유효합니다. 그러나 두 요소에 대해 std::forward에는 하나의 템플릿 매개 변수와 하나의 함수 매개 변수가 있기 때문에 변형 2는 bar(std::forward<T1, T2>(t1, t2))으로 확장됩니다.

변형 1은 작동하지만 변형 2는 하나의 요소가있는 매개 변수 팩의 경우에만 유효합니다. 단일 템플릿 인수 만 신경 쓰면 가변 템플릿을 전혀 사용하지 않아야합니다 !)

기본적으로 팩 확장은 PATTERN...이어야합니다. 여기서 pattern은 팩의 각 요소에 대해 반복 할 항목입니다. 각 요소에 대해 std::forward<T>(t)을 호출하려는 경우 패턴은 std::forward<Args>(args)이어야하며 전체 패키지 확장은 ...내부가 인 패턴이 아니며 두 개의 별도 팩 확장이 발생합니다. 유형은 Args이고 변수 중 하나는 args입니다.

+0

줄임표 혼동에 대해 죄송합니다. –

+1

흠, 팩이 비어 있다면 두 번째 팩이'std :: forward <>()'로 확장되지 않습니까? –

+0

@DanielFrey'std :: forward (args) ...'는 확장되지 않습니다. 'std :: forward (args ...)'는'std :: forward <>()'로 확장됩니다. –

관련 문제