470,849 Members | 1,095 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,849 developers. It's quick & easy.

template error with iterator

Dear all,

I was experimenting with a template taking two iterators for the range
of
a vector.(Perhaps, it is sth simple and I am missing it because it is
a
late hour.) I ran into problems in the compile phase , the code is
below:

#include <iostream>
#include <algorithm>
#include <stdexcept>
#include <vector>

using std::domain_error;
using std::sort;
using std::vector;

template <class T, class Ran>
T median(Ran b, Ran e)
{
typedef typename vector<T>::size_type vec_sz;

vec_sz size = (e-b)/sizeof(T);
if (size == 0)
throw domain_error("median of an empty vector");

sort(b, e);

vec_sz mid = size/2;

return size % 2 == 0 ? (b[mid] + b[mid-1]) / 2 : b[mid];
}

int main()
{
vector<doublevec;
for(int i=0;i!=10;++i)
vec.push_back(i);
std::cout << median(vec.begin(), vec.end()) << std::endl;
return 0;
}
I get

83.cc: In function 'int main()':
83.cc:38: error: no matching function for call to
'median(__gnu_cxx::__normal_iterator<double*, std::vector<double,
std::allocator<double >, __gnu_cxx::__normal_iterator<double*,
std::vector<double, std::allocator<double >)'

I am supplying the median function with iterators by using the begin
and
end member functions of the vector. However, I get a type mismatch
error
on iterators I guess. Could you clarify the problem for me?

Rgds,

--
Umut
Jun 27 '08 #1
7 1494
On May 13, 1:37 am, utab <umut.ta...@gmail.comwrote:
Dear all,

I was experimenting with a template taking two iterators for the range
of
a vector.(Perhaps, it is sth simple and I am missing it because it is
a
late hour.) I ran into problems in the compile phase , the code is
below:

#include <iostream>
#include <algorithm>
#include <stdexcept>
#include <vector>

using std::domain_error;
using std::sort;
using std::vector;

template <class T, class Ran>
T median(Ran b, Ran e)
{
typedef typename vector<T>::size_type vec_sz;

vec_sz size = (e-b)/sizeof(T);
if (size == 0)
throw domain_error("median of an empty vector");

sort(b, e);

vec_sz mid = size/2;

return size % 2 == 0 ? (b[mid] + b[mid-1]) / 2 : b[mid];

}

int main()
{
vector<doublevec;
for(int i=0;i!=10;++i)
vec.push_back(i);
std::cout << median(vec.begin(), vec.end()) << std::endl;
return 0;

}

I get

83.cc: In function 'int main()':
83.cc:38: error: no matching function for call to
'median(__gnu_cxx::__normal_iterator<double*, std::vector<double,
std::allocator<double >, __gnu_cxx::__normal_iterator<double*,
std::vector<double, std::allocator<double >)'

I am supplying the median function with iterators by using the begin
and
end member functions of the vector. However, I get a type mismatch
error
on iterators I guess. Could you clarify the problem for me?

Rgds,

--
Umut
Forgot to tell that I use g++ 4.1.2
Jun 27 '08 #2
On 13 May, 00:37, utab <umut.ta...@gmail.comwrote:
>
template <class T, class Ran>
T median(Ran b, Ran e)
{
* typedef typename vector<T>::size_type vec_sz;

* vec_sz size = (e-b)/sizeof(T);
* if (size == 0)
* * throw domain_error("median of an empty vector");

* sort(b, e);

* vec_sz mid = size/2;

* return size % 2 == 0 ? (b[mid] + b[mid-1]) / 2 : b[mid];

}

int main()
{
* vector<doublevec;
* for(int i=0;i!=10;++i)
* * vec.push_back(i);
* std::cout << median(vec.begin(), vec.end()) << std::endl;
The compiler cannot deduce T; replace the above call with
median<double>(vec.begin(), vec.end())
^^^^^^
* return 0;

}
Jun 27 '08 #3
On May 13, 1:47 am, tragomaskhalos <dave.du.verg...@logicacmg.com>
wrote:
On 13 May, 00:37, utab <umut.ta...@gmail.comwrote:


template <class T, class Ran>
T median(Ran b, Ran e)
{
typedef typename vector<T>::size_type vec_sz;
vec_sz size = (e-b)/sizeof(T);
if (size == 0)
throw domain_error("median of an empty vector");
sort(b, e);
vec_sz mid = size/2;
return size % 2 == 0 ? (b[mid] + b[mid-1]) / 2 : b[mid];
}
int main()
{
vector<doublevec;
for(int i=0;i!=10;++i)
vec.push_back(i);
std::cout << median(vec.begin(), vec.end()) << std::endl;

The compiler cannot deduce T; replace the above call with
median<double>(vec.begin(), vec.end())
^^^^^^
return 0;
}
Thanks, I read something similar in the faq as well.
Jun 27 '08 #4
On May 12, 4:37 pm, utab <umut.ta...@gmail.comwrote:
template <class T, class Ran>
T median(Ran b, Ran e)
{
According to that definition, there is no relation between T and Ran.

[...]
std::cout << median(vec.begin(), vec.end()) << std::endl;
The complier cannot deduce T for that call because the return values
are never a part of function signatures. You can try specifying it
yourself:

median<double>(vec.begin(), vec.end());

Ali
Jun 27 '08 #5
utab <um********@gmail.comwrote in news:50129083-18fd-4099-9ba7-
58**********@a23g2000hsc.googlegroups.com:
Dear all,

I was experimenting with a template taking two iterators for the range
of
a vector.(Perhaps, it is sth simple and I am missing it because it is
a
late hour.) I ran into problems in the compile phase , the code is
below:

#include <iostream>
#include <algorithm>
#include <stdexcept>
#include <vector>

using std::domain_error;
using std::sort;
using std::vector;

template <class T, class Ran>
T median(Ran b, Ran e)
{
You are passing in only Ran arguments, there is no way the compiler could
deduce the T template parameter.
typedef typename vector<T>::size_type vec_sz;

vec_sz size = (e-b)/sizeof(T);
if (size == 0)
throw domain_error("median of an empty vector");

sort(b, e);

vec_sz mid = size/2;

return size % 2 == 0 ? (b[mid] + b[mid-1]) / 2 : b[mid];
}

int main()
{
vector<doublevec;
for(int i=0;i!=10;++i)
vec.push_back(i);
std::cout << median(vec.begin(), vec.end()) << std::endl;
... so you have to specify it yourself:

std::cout << median<double>(vec.begin(), vec.end()) << std::endl;

... or throw away the redundant template parameter:

template <class Ran>
typename Ran::value_type median(Ran b, Ran e)
{
typedef typename vector<Ran::value_type>::size_type vec_sz;

vec_sz size = (e-b)/sizeof(Ran::value_type);
if (size == 0)
throw domain_error("median of an empty vector");

....

hth
Paavo
Jun 27 '08 #6
On May 12, 4:37*pm, utab <umut.ta...@gmail.comwrote:
I was experimenting with a template taking two iterators for the range
of
a vector.(Perhaps, it is sth simple and I am missing it because it is
a
late hour.) I ran into problems in the compile phase , the code is
below:

#include <iostream>
#include <algorithm>
#include <stdexcept>
#include <vector>

using std::domain_error;
using std::sort;
using std::vector;

template <class T, class Ran>
T median(Ran b, Ran e)
{
* typedef typename vector<T>::size_type vec_sz;

* vec_sz size = (e-b)/sizeof(T);
* if (size == 0)
* * throw domain_error("median of an empty vector");

* sort(b, e);

* vec_sz mid = size/2;

* return size % 2 == 0 ? (b[mid] + b[mid-1]) / 2 : b[mid];
}
The C++ compiler is not able to deduce the type "T" from the median()
function call. Since "T" is dependent on the iterator type "Ran", I
would eliminate "T" altogether. Note also that the calculation of
"size" is incorrect - e-b will return the number of positions between
two random access iterators.

Applying these suggestions produces a program like this one:

#include <iostream>
#include <algorithm>
#include <stdexcept>
#include <vector>
#include <iterator>

using std::domain_error;
using std::sort;
using std::vector;

template <class Ran>
typename std::iterator_traits<Ran>::value_type
median(Ran b, Ran e)
{
size_t size = e-b;
if (size == 0)
throw domain_error("median of an empty vector");
sort(b, e);
size_t mid = size/2;
return size % 2 == 0 ? (b[mid] + b[mid-1]) / 2 : b[mid];
}

int main()
{
vector<doublevec;

for (int i=0; i!=10; ++i)
vec.push_back(i);

std::cout << median(vec.begin(), vec.end()) << std::endl;
return 0;
}

Greg
Jun 27 '08 #7
On May 13, 1:57 am, Paavo Helde <nob...@ebi.eewrote:
utab <umut.ta...@gmail.comwrote in news:50129083-18fd-4099-9ba7-
586bb9df7...@a23g2000hsc.googlegroups.com:
I was experimenting with a template taking two iterators for
the range of a vector.(Perhaps, it is sth simple and I am
missing it because it is a late hour.) I ran into problems
in the compile phase , the code is below:
[...]
.. or throw away the redundant template parameter:
template <class Ran>
typename Ran::value_type median(Ran b, Ran e)
There's no guarantee that Ran has a typedef for value_type (and
there have definitely been implementations of the standard
library where it didn't for std::vector<>).

This should be:

template< typename RandomAccessIterator >
typename std::iterator_traits< RandomAccessIterator >::value_type
median( RandomAccessIterator begin, RandomAccessIterator end )
{
typedef typename vector<Ran::value_type>::size_type vec_sz;
And here, even worse, since you're tying yourself to
std::vector. (Even as it stands, you need an additional
typename in the template argument.) Also, the difference
between to random access iterators is a difference_type, not a
size_type. So it should be:

typedef typename std::iterator_traits< RandomAccessIterator >
::difference_type SequenceSize ;
vec_sz size = (e-b)/sizeof(Ran::value_type);
And of course, you don't want the division.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #8

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Dave O'Hearn | last post: by
1 post views Thread by darkstorm | last post: by
4 posts views Thread by red floyd | last post: by
8 posts views Thread by Fab | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.