문제

일반적인 함수 템플릿 서명:

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;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top