Question

A typical function template signature:

template<typename Iterator, typename T>
T fn(Iterator first, Iterator last, T init)
{
    T result;
    // ...
    return result;
}

The problem is, when I call it like this:

std::vector<long> data(1000,1);
fn(data.begin(), data.end(), 0);

or any other way without explicitly calling

fn<std::vector<long>::iterator, long>(data.begin(), data.end(),0);

then the type of T is an int, and there is a risk of overflow and bad results in fn.

So how do I specialize fn so that the call to

fn(data.begin(), data.end(), 0);

is unambigous and results in T to be set to Iterator::value_type? The choice

template<Iterator>
typename iterator_traits<Iterator>::value_type fn(Iterator first, Iterator last, typename iterator_traits<Iterator>::value_type init)
{
    //...
}

results in an ambiguous call error from g++/clang++.

EDIT:

I see my mistake now and the above code works with @Lightness Races suggestion below. Thanks for the help.

Was it helpful?

Solution

Why not simply pass a long?

fn(data.begin(), data.end(), 0L);

Beyond that you could probably do something like this:

#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
);

Live demo

I don't really see how you're at risk of an overflow, though.

OTHER TIPS

As:

0 is an int
0L is a long

You just have to call the method with the correct argument:

  • Use directly the correct literal

as:

fn(data.begin(), data.end(), 0L);
  • Or, you may use an intermediate variable

as:

long init = 0; // result in 0L

fn(data.begin(), data.end(), init);
  • or you may cast the value:

as:

fn(data.begin(), data.end(), static_cast<long>(0));

One way to write fn to avoid to call it correctly is

template<typename Iterator>
auto fn(Iterator first, Iterator last, typename std::decay<decltype(*first)>::type init)
    -> typename std::decay<decltype(*first)>::type;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top