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
Is Make_Shared Really More Efficient Than New
Switch "Transfer of Control Bypasses Initialization Of:" When Calling a Function
Pros & Cons of Putting All Code in Header Files in C++
Is Boost Shared_Ptr <Xxx> Thread Safe
Attribute & Reflection Libraries for C++
Gcc: Difference Between -O3 and -Os
How to Build Boost with New Visual Studio 2013 Preview
How to Test an Exe with Google Test
Linux Optimistic Malloc: Will New Always Throw When Out of Memory
Use-Cases of Pure Virtual Functions with Body
Is There a Standard Way of Moving a Range into a Vector
What Is the Meaning of Template<> with Empty Angle Brackets in C++
How to Create a C++ Boost Undirected Graph and Traverse It in Depth First Search (Dfs) Order
Mock Non-Virtual Method C++ (Gmock)