In C++, template argument deduction doesn’t work for function return type. One solution is using nested type like below:
template< class T >
struct MyIter {
typedef T value_type; // nested type
T* ptr_;
MyIter( T* p=nullptr ) : ptr_( p ){}
T& operator*() const { return *ptr_; }
};
template< class I >
typename I::value_type func( I iter )
{
return *iter;
}
// ...
MyIter< int > iter( new int(8) );
cout << func( iter ); // Output: 8
A drawback of this approach is not all iters are of class type, e.g. raw pointer. It’s not possible to define nested type for a raw pointer.
Traits and Template partial specialisation can address this.
// Traits
template< class I >
struct iterator_traits
{
typedef typename I::value_type value_type;
}
// Template Partial Specialisation for T*
template< class T >
typename iterator_traits< T* >
{
typedef T value_type;
}
// Template Partial Specialisation for const T*
template< class T >
typename iterator_traits< const T* >
{
typedef T value_type; // Note, here should be T rather than const T
}
The above func() could be written like below:
template< class I >
typename iterator_traits< I >::value_type func( I iter )
{
return *iter;
}