Implicit conversion in template type deduction

user1508519

In this question the OP asks why his std::accumulate function is returning the wrong value. The answer is because he passes in an int for his initial value, therefore making the calculations all ints rather than doubles. I have two versions:

template <class InputIterator, class T>
auto accumulate (InputIterator first, InputIterator last, T init)
{
  typedef typename std::iterator_traits<InputIterator>::value_type vt;
  vt init2 = vt(init);
  // ...
  return init2;
}

template <class InputIterator, class T = typename std::iterator_traits<InputIterator>::value_type>
T not_working (InputIterator first, InputIterator last, T init)
{
// ...
return init;
}

Why in version 2 is T still an int? Because of implicit conversion?

Dietmar Kühl

The answer to the immediate question was already stated: if the type can be deduced from the argument list, it will be deduced. Making the used type a nested type prevents it from being deduced:

template <typename T>
struct identity {
    typedef T type;
};
template <typename It, typename T = typename std::iterator_traits<It>::value_type>
T safe_accumulate(It begin, It end, typename identity<T>::type sum) {
    return std::accumulate(begin, end, sum);
}

In some situations it is, however, desirable to specify the result type of the algorithm. For example, if you want to sum the char values in a lengthy strings. Using safe_accumulate() as it is defined above makes specifying the result type a bit painful:

std::string s("hello, world");
std::cout << safe_accumulate<std::string::iterator, long>(s.begin(), s.end(), 0) << '\n';

The implementation can be done in a way which puts the result type first:

template <typename T = void, typename It>
typename std::conditional<std::is_same<T, void>::value,
    typename std::iterator_traits<It>::value_type,
    T>::type
safe_accumulate(It begin, It end,
                typename std::conditional<std::is_same<T, void>::value,
                    typename std::iterator_traits<It>::value_type,
                    T>::type sum) {
    return std::accumulate(begin, end, sum);
}

Now the algorithm can be used in a more convenient way, i.e., the implementer of the algorithm provided a somewhat more complicated implementation for the benefit of its users:

std::cout << safe_accumulate<long>(s.begin(), s.end(), 0) << '\n';

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Implicit conversion in template type deduction

From Dev

Template type-deduction performs implicit array-to-pointer conversion

From Dev

Template argument type deduction by conversion operator

From Dev

Allow implicit type conversion during template evaluation

From Dev

What is wrong with inferred type of template and implicit type conversion?

From Dev

Partial template type deduction

From Dev

Template parameter type deduction

From Dev

Template type deduction

From Dev

How implicit conversion works for non-type template parameters?

From Dev

Implicit conversion for generic type?

From Dev

Swift implicit conversion of type

From Dev

Implicit conversion of function type

From Dev

Implicit type conversion with structs

From Dev

Implicit type conversion with structs

From Dev

Template type deduction of template class with template member

From Dev

Template type deduction for rvalue arguments

From Dev

Base resolution/template type deduction

From Dev

Template type deduction with std::function

From Dev

Template type deduction: distinguish by typedef

From Dev

Nested template parameters and type deduction

From Dev

Std::forward and template type deduction

From Dev

template argument deduction of return type in function template

From Dev

template argument deduction of return type in function template

From Dev

Template type deduction in parameter and return type

From Dev

Implicit type conversion for lambda expression

From Dev

Entity Framework Implicit Type Conversion

From Dev

Implicit integer type conversion in C

From Dev

Implicit Data Type Conversion in Oracle

From Dev

Implicit type conversion with reference to void*

Related Related

HotTag

Archive