C++ Template Typename Iterator

C++ template typename iterator

In list<tNode<T>*>::iterator, you have a dependant name, that is, a name that depends on a template parameter.

As such, the compiler can't inspect list<tNode<T>*> (it doesn't have its definition at this point) and so it doesn't know whether list<tNode<T>*>::iterator is either a static field or a type.

In such a situation, the compiler assumes that it is a field, so in your case it yields a syntax error. To solve the issue, just tell the compiler that it is a type by putting a typename ahead of the declaration:

typename list<tNode<T>*>::iterator it

How to use iterator as a template parameter and return its value?

You can use std::iterator_traits

template<typename Iterator>
typename std::iterator_traits<Iterator>::reference
foo(Iterator begin, Iterator end)
{
vector<typename std::iterator_traits<Iterator>::value_type> v(begin, end);
//do something
return *begin;
}

auto and decltype is an alternative:

template<typename Iterator>
decltype(auto) // C++14
foo(Iterator begin, Iterator end)
// or auto foo(..) -> decltype(*begin) in C++11
{
std::vector<std::decay_t<decltype(*begin)>> v(begin, end);
//do something
return *begin;
}

c++ iterator with template

Add a typename before the iterator

#include <iostream>
#include <vector>

template <class T>
void my_print(std::vector<T> input)
{
for (typename std::vector<T>::iterator pp = input.begin(); pp != input.end(); ++pp)
{
std::cout << *pp << "\n";
}
}
int main(int argc, char* argv[])
{
std::vector<int> aa(10, 9);
my_print(aa);

return 0;
}

source: http://www.daniweb.com/software-development/cpp/threads/187603/template-function-vector-iterator-wont-compile

C++11 Using Iterators for Vectors of Template Parameter Types

You should use typename here, because std::vector<ObjectType*> is a dependent type name which depends on the template parameter ObjectType.

typename std::vector<ObjectType*>::iterator begin();
typename std::vector<ObjectType*>::iterator end();

$14.6/2 Name resolution [temp.res]

A name used in a template declaration or definition and that is
dependent on a template-parameter is assumed not to name a type unless
the applicable name lookup finds a type name or the name is qualified
by the keyword typename.

iterators in c++ template class

The problem is that you want to deduce the E in Array<E>::Iterator from x.begin() that is an Array<int>::Iterator. But that is simply not possible.

Your best option is probably to write:

template <typename IT>
T printBegin(IT it){ return (T)*it;}

If, for any reason, you need to use the E type, then it is better to add a nested typedef:

class Iterator:public std::iterator<std::output_iterator_tag, T>{
public:
typename T array_member_type;
//...
};

And then:

template <typename IT>
T printBegin(IT it){
typedef typename IT::array_member_type E;
return (T)*it;
}

Wait! Your iterator derives from std::iterator so the typedef already exists. No need to redefine:

template <typename IT>
T printBegin(IT it){
typedef typename IT::value_type E;
return (T)*it;
}

Container Iterator Template for one value type

Your example 2 is nearly correct

template<
template<typename T> class C,
typename T,
typename C<T>::iterator iterator // That is wrong
>
Errc const& process(typename C<T>::iterator begin, typename C<T>::iterator end);

it should be:

template<template <typename> class C, typename T>
Errc const& process(typename C<T>::iterator begin, typename C<T>::iterator end);

But issue is that C/T are not deducible, and you have to call it like:

process<std::vector, std::complex<float>>(v.begin(), v.end());

And C-array and std::array doesn't match template <typename> class C neither (and std::vector has default allocator too :-/)

Simpler would just be

template<typename Iterator>
Errc const& process(Iterator begin, Iterator end);

possibly with some SFINAE

template <typename Iterator,
std::enable_if_t<std::is_same_v<std::complex<float>,
std::iterator_traits<Iterator>::value_type>, int> = 0>
Errc const& process(Iterator begin, Iterator end);

or C++20 requires:

template <typename Iterator>
Errc const& process(Iterator begin, Iterator end)
requires (std::is_same_v<std::complex<float>, std::iterator_traits<Iterator>::value_type);

If you want only contiguous sequences, you might use std::span

Errc const& process(std::span<std::complex<float>)

How to specialize a function template with iterator traits?

You can avoid specializations, or writing another overload. Instead, you can use conditional_t to select a specific type according to some condition

// alias for convenience
using T = typename std::iterator_traits<ForwIt>::value_type;

// if T is int, value_type is double, otherwise it's just T
using value_type = std::conditional_t<std::is_same_v<T, int>, double, T>;

For the return type, simply use auto, and the correct type will be deduced from the type of baz.

Here's a demo



Related Topics



Leave a reply



Submit