Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to let template function automatically deduce an iterator's underlying data type?

I have a function where I need an iterator's underlying data type as return type, like this:

#include <iostream>
#include <vector>
#include <iterator>

template<class T, class ForwardIterator>
std::vector<T> get_odd(ForwardIterator data_begin, ForwardIterator data_end)
{
    std::vector<T> ret;
    std::copy_if(data_begin, data_end, std::back_inserter(ret), [](int x) { return x % 2; });
    return ret;
}

int main()
{
    std::vector<int> vi { 1, 2, 3, 4, 5 };
    for (auto i : get_odd<int>(vi.begin(), vi.end()))
        std::cout << i << ", ";
    std::cout << std::endl;

    std::vector<unsigned int> vui{ 9UL, 8UL, 7UL, 6UL, 5UL };
    // Note the 'char' I provided to the function, this will print weird chars
    for (auto i : get_odd<char>(vui.begin(), vui.end()))
        std::cout << i << ", ";
    std::cout << std::endl;

    return 0;
}

In the main(), I have to explicitly provide data type 'int' or 'char' to the get_odd function, is there a way to find out iterator's underlying data type, and let template automatically deduct the correct data type?

like image 225
dguan Avatar asked Aug 21 '14 15:08

dguan


People also ask

When the actual code for a template function is generated?

A code for template function is generated when the function is instantiated. The functions are often instantiated when they are first time called (in the code), but there are other ways to instantiate a function - do a so-called 'explicit instantiation'.

What is a template function?

Function templates are similar to class templates but define a family of functions. With function templates, you can specify a set of functions that are based on the same code but act on different types or classes.

How do you call a function in a template?

A function template starts with the keyword template followed by template parameter(s) inside <> which is followed by the function definition. In the above code, T is a template argument that accepts different data types ( int , float , etc.), and typename is a keyword.

Which one is suitable syntax for function template?

Which one is suitable syntax for function template? Explanation: Both class and typename keywords can be used alternatively for specifying a generic type in a template.


1 Answers

Iterator properties can be queried using std::iterator_traits:

template<class ForwardIterator>
std::vector<typename std::iterator_traits<ForwardIterator>::value_type> 
get_odd(ForwardIterator data_begin, ForwardIterator data_end)
{
    std::vector<typename std::iterator_traits<ForwardIterator>::value_type> ret;
    std::copy_if(data_begin, data_end, std::back_inserter(ret), [](int x) { return x % 2; });
    return ret;
}
like image 137
Angew is no longer proud of SO Avatar answered Sep 28 '22 19:09

Angew is no longer proud of SO