템플릿 인수 추론의 모호한 호출 해결
-
21-12-2019 - |
문제
일반적인 함수 템플릿 서명:
template<typename Iterator, typename T>
T fn(Iterator first, Iterator last, T init)
{
T result;
// ...
return result;
}
문제는 다음과 같이 호출할 때입니다.
std::vector<long> data(1000,1);
fn(data.begin(), data.end(), 0);
또는 명시적으로 호출하지 않고 다른 방법으로
fn<std::vector<long>::iterator, long>(data.begin(), data.end(),0);
T의 유형은 int
, 오버플로 및 나쁜 결과의 위험이 있습니다. fn
.
그럼 어떻게 전문화할 것인가? fn
그래서 호출은
fn(data.begin(), data.end(), 0);
모호하지 않으며 결과는 다음과 같습니다. T
으로 설정하다 Iterator::value_type
?선택
template<Iterator>
typename iterator_traits<Iterator>::value_type fn(Iterator first, Iterator last, typename iterator_traits<Iterator>::value_type init)
{
//...
}
g++/clang++에서 모호한 호출 오류가 발생합니다.
편집하다:
이제 내 실수를 확인했으며 위 코드는 아래 @Lightness Races 제안과 함께 작동합니다.도와 주셔서 감사합니다.
해결책
단순히 오래 지나지 않아?
fn(data.begin(), data.end(), 0L);
.
당신을 그 이상으로 당신은 아마이 일을 할 수 있습니다 :
#include <type_traits>
template<typename Iterator>
typename std::iterator_traits<Iterator>::value_type fn(
Iterator first,
Iterator last,
typename std::iterator_traits<Iterator>::value_type init
);
.
라이브 데모
나는 당신이 얼마나 오버 플로우의 위험에 처한지 정말로 보이지 않는다.
다른 팁
처럼:
0 is an int
0L is a long
올바른 인수를 사용하여 메서드를 호출하면 됩니다.
- 올바른 리터럴을 직접 사용하세요.
처럼:
fn(data.begin(), data.end(), 0L);
- 또는 중간 변수를 사용할 수도 있습니다.
처럼:
long init = 0; // result in 0L
fn(data.begin(), data.end(), init);
- 또는 다음과 같이 값을 캐스팅할 수 있습니다.
처럼:
fn(data.begin(), data.end(), static_cast<long>(0));
글을 쓰는 한 가지 방법 fn
올바르게 호출하지 않는 것은
template<typename Iterator>
auto fn(Iterator first, Iterator last, typename std::decay<decltype(*first)>::type init)
-> typename std::decay<decltype(*first)>::type;
제휴하지 않습니다 StackOverflow