2016-08-25 5 views
8

C++ 17에서는 instantiate objects without specifying the template types이 가능합니다. 기본적으로,이 코드는 컴파일 것 :C++에서 전달 참조를 사용할 때 템플릿 구조체에 std :: decay가 필요합니까?

std::pair p(2, 4.5);  // deduces to std::pair<int, double> p(2, 4.5); 
std::tuple t(4, 3, 2.5); // same as auto t = std::make_tuple(4, 3, 2.5); 

을 따라서 아래의 코드 가정 :

template<typename... Ts> 
struct Foo 
{ 
    Foo(Ts&&... ts) : 
     ts{std::forward_as_tuple(ts...)} 
    {} 

    std::tuple<Ts...> ts; 
}; 

int main() 
{ 
    auto f = [] { return 42; }; 
    Foo foo{f, [] { return 84; }}; 
} 

나는이 같은 튜플 선언에 std::decay 사용해야을? 나는 푸의 생성자에서이 패턴을 볼 수 있습니다

template<typename T> 
auto make_baz(T&& t) -> baz<std::decay_t<T>>; 

그리고, 그것을 전달을 사용하고이 때문에

std::tuple<std::decay_t<Ts>...> ts; 

내가 추론 템플릿 유형에 따라 객체를 반환하는 함수를 써서 어떻게 참조가 튜플에 값을 올바르게 전달합니다. 여기서 유형 공제가 같은 방식으로 작동하는지 확실하지 않습니다.

+0

왜 공제 안내서를 추가하지 않으시겠습니까? – cpplearner

+0

@cpplearner Foo의 인스턴스화를 위해 이미 유형 공제가 있습니다. 나는 공제 가이드를위한 어떤 이점도 보지 못하거나, 내가 놓친 것이 있습니까? –

답변

4

클래스 템플릿 내부의 클래스 공제를 사용하기 위해 클래스의 내부 구조를 변경할 필요가 없습니다. 그게 공제 지침서입니다.

시작하기 가장 좋은 곳은 make_X 함수를 작성하는 것입니다. 당신이 제공하든 안하든간에 원하는 서명을 결정하면 명시 적 공제 가이드를 작성해야하는지 또는 생성자에서 유추 된 암시 적 공제 지침에 의존 할 수 있는지 알려줍니다.

실제로 차감 가이드는 암시 적이든 명시 적이든 관계없이 make_X 함수와 동일하게 작동합니다 (생성자 추출까지).

당신의 다음 선언했을 makeFoo을 원하는 :이 템플릿 인수에 변환을 수행하기 때문에

template<typename... Ts> 
auto makeFoo(Ts&&... ts) -> Foo<std::decay_t<Ts>...>; 

을, 당신은 명시 적으로 공제 가이드를 제공해야합니다; 이것은 auto make 제거 단지로, makeFoo의 선언과 문법적으로 동일하다 : 그 이외의 모든 종류의 변환없이, 당신은 명시 적으로 공제 가이드를 제공하지 않으면

template<typename... Ts> 
Foo(Ts&&... ts) -> Foo<std::decay_t<Ts>...>; 

, 하나의 생성자에서 생성 될 템플릿 인수 공제 동안 발생이 당신이 원하는 것을하지

template<typename... Ts> 
Foo(Ts&&... ts) -> Foo<Ts...>; 

, 그것은 std::decay_t을 적용하지 않기 때문에. 클래스 내부를 수정하면 (std::decay_t에서 ts까지) 작동하지만 명시 적 공제 안내가 문제를 해결할 때는 불필요합니다.

+0

오브젝트 선언에 대해 유형 공제가 발생한다고 가정하면 어떤 이점이 있습니까? –

+0

죄송합니다. "그"는 무슨 뜻입니까? 'decay_t' 또는 다른 것을 의미합니까? – ecatmur

+0

공제 가이드. C++ 17에서는 Foo 인스턴스화시이 문제가 발생하므로 유형을 지정하지 않아도됩니다. 미안, 내 질문에 명확하지 않은 경우 : 내가 원하는 건 내가 lvalue를 생성자에 전달하면 Foo에서 T에 대한 유형 공제가 참조인지 여부를 알 수 있습니다. 내 질문을 수정하겠습니다. –