템플릿 추론 가이드 란 무엇이며 언제 사용해야합니까?


87

C ++ 17 표준은 "템플릿 추론 가이드"를 도입합니다. 이 표준 버전에 도입 된 생성자에 대한 새로운 템플릿 인수 추론과 관련이 있다고 생각하지만, 그것이 무엇인지, 무엇을위한 것인지에 대한 간단한 FAQ 스타일의 설명은 아직 보지 못했습니다.

  • C ++ 17의 템플릿 추론 가이드 란 무엇입니까?

  • 왜 (그리고 언제) 그것들이 필요합니까?

  • 어떻게 신고합니까?



특히 C ++ 17 STL (예 : std :: pair 또는 std :: tuple)에서 실제로 제공되는 추론 가이드가 있는지 알고 싶습니다. C ++ 17에서 "추론 가능한"표준 템플릿 유형의 전체 목록은 무엇입니까?
Quuxplusone


어떤 컴파일러가 이것을 지원하는지 알고 싶습니다. gcc, clang 및 vc ++를 시도했습니다. rextester.com/DHPHC32332 신경 쓰지 마세요. gc ++ 8.1 C ++ 17 및 2a g ++ -std = c ++ 17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
Jean-Simon Brochu 2019-02-04

답변:


98

템플릿 추론 가이드는 컴파일러에게 생성자 인수 집합 (및 해당 유형)을 클래스의 템플릿 매개 변수로 변환하는 방법을 알려주는 템플릿 클래스와 관련된 패턴입니다.

가장 간단한 예는 of std::vector및 반복기 쌍을 취하는 생성자입니다.

template<typename Iterator>
void func(Iterator first, Iterator last)
{
  vector v(first, last);
}

컴파일러는 vector<T>T유형이 무엇인지 파악해야 합니다. 우리는 답이 무엇인지 압니다. T이어야합니다 typename std::iterator_traits<Iterator>::value_type. 그러나 입력 하지 않고 컴파일러에게 어떻게 알릴 vector<typename std::iterator_traits<Iterator>::value_type>까요?

공제 가이드를 사용합니다.

template<typename Iterator> vector(Iterator b, Iterator e) -> 
    vector<typename std::iterator_traits<Iterator>::value_type>;

이는 컴파일러에게 vector해당 패턴과 일치 하는 생성자 를 호출 할 때 vector의 오른쪽에있는 코드를 사용하여 특수화를 추론 한다는 것을 알려줍니다 ->.

인수에서 유형을 추론하는 것이 해당 인수 중 하나의 유형을 기반으로하지 않는 경우 가이드가 필요합니다. 에서를 초기화 vector하면 initializer_list명시 적으로 vector's가 사용 T되므로 가이드가 필요하지 않습니다.

왼쪽은 반드시 실제 생성자를 지정하지 않습니다. 작동 방식은 형식에 대해 템플릿 생성자 추론을 사용하는 경우 모든 추론 가이드에 대해 전달하는 인수와 일치한다는 것입니다 (기본 템플릿의 실제 생성자는 암시 적 가이드를 제공함). 일치하는 항목이 있으면이를 사용하여 유형에 제공 할 템플릿 인수를 결정합니다.

그러나 일단 추론이 완료되면 컴파일러가 유형에 대한 템플릿 매개 변수를 파악하면 해당 유형의 객체에 대한 초기화는 아무 일도 발생하지 않은 것처럼 진행됩니다. 즉, 선택한 추론 가이드가 선택한 생성자 와 일치하지 않아도됩니다 .

이는 또한 집계 및 집계 초기화와 함께 가이드를 사용할 수 있음을 의미합니다.

template<typename T>
struct Thingy
{
  T t;
};

Thingy(const char *) -> Thingy<std::string>;

Thingy thing{"A String"}; //thing.t is a `std::string`.

따라서 추론 가이드는 초기화되는 유형을 파악하는 데만 사용됩니다. 초기화의 실제 프로세스는 일단 결정이 이루어지면 이전과 똑같이 작동합니다.


7
흠, 가이드가 있어도 vector v{first, last};옳은 일을하지 않을 것
TC

3
@TC… 옳은 일이 반복자의 벡터를 만드는 것이 아니라면. 그리고 std::string{32,'*'}[0] == ' '(ASCII의 경우). 그러나 이것은 C ++ 11 이후로 모두 사실이었습니다.
Arne Vogel

2
할당 자 벡터 매개 변수는 어떻게됩니까? 할당 자 벡터 매개 변수에 기본 인수가 없으면 어떻게됩니까? (
InputIterator

@NicolBolas : 부분적으로 또는 완전히 전문화 된 클래스의 컨텍스트에서 암시 적 및 명시 적 추론 가이드가 어떻게 작동 할 수 있는지에 대한 세부 정보를 설명해 주시겠습니까? 빠른 검색을 통해 이에 대한 정보를 찾기가 어렵습니다.
user541686 jul.

1
@NicolBolas : 알겠습니다. 이 질문이 명시적인 추론 가이드에 관한 것이라는 것은 저에게 분명하지 않습니다.이 댓글에 문자 그대로 쓴 내용 만 포함하면 도움이 될 것 같습니다.
user541686 jul.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.