Why doesn't this work?

  • Thread starter Steven T. Hatton
  • Start date
S

Steven T. Hatton

Could someone explain this to me?

/*
* the headers and using declarations are the same for both examples
*/
#include <sstream>
#include <algorithm>
#include <iostream>
#include <utility>
#include <vector>
#include <string>

using std::stringstream;
using std::eek:stream;
using std::make_pair;
using std::endl;
using std::vector;
using std::pair;
using std::string;

/*
* This compiles. Note the pair<int, int>
*/
template <typename Tf, typename Ts>
ostream& print_pair_vector(const vector<pair<Tf,Ts> >& vec, ostream& out,
const string& name="v")
{
typedef vector<pair<int, int> >::const_iterator vpp_itr;
for(vpp_itr it = vec.begin(); it < vec.end(); it++) {
size_t i = it -vec.begin();
out << name << "["<< i << "].first= " << it->first
<< name << "["<< i << "].second=" << it->second
<< endl;
}
return out;
}

/*
* This won't compile. Note the pair<Tf, Ts> where <int, int> is above.
* The errors I get are shown below.
*/
template <typename Tf, typename Ts>
ostream& print_pair_vector(const vector<pair<Tf,Ts> >& vec, ostream& out,
const string& name="v")
{
typedef vector<pair<Tf, Ts> >::const_iterator vpp_itr;
for(vpp_itr it = vec.begin(); it < vec.end(); it++) {
size_t i = it -vec.begin();
out << name << "["<< i << "].first= " << it->first
<< name << "["<< i << "].second=" << it->second
<< endl;
}
return out;
}

/* error messages
g++ -o stacker Stacker.cpp main.cpp
Stacker.cpp: In function `std::eek:stream& print_pair_vector(const
std::vector<std::pair<_T1, _T2>, std::allocator<std::pair<_T1, _T2> > >&,
std::eek:stream&, const std::string&)':
Stacker.cpp:21: error: expected init-declarator before "vpp_itr"
Stacker.cpp:21: error: expected `,' or `;' before "vpp_itr"
Stacker.cpp:22: error: `vpp_itr' undeclared (first use this function)
Stacker.cpp:22: error: (Each undeclared identifier is reported only once for
each function it appears in.)
Stacker.cpp:22: error: expected `;' before "it"
Stacker.cpp:22: error: `it' undeclared (first use this function)
*/
 
R

Ron Natalie

Steven T. Hatton said:
Could someone explain this to me?

Let me give you a hint. When posting to the group, please flag the lines that are
indicated by your compiler messages. People have better things to do than count lines.
typedef vector<pair<Tf, Ts> >::const_iterator vpp_itr;

typedef typename vector<pair<Tf,Ts> >::const_iterator vpp_itr;

Qualified names that depend on template varables need typename to distinguish
it as a type as opposed to a member name.
 
B

bartek

Could someone explain this to me?
(...)

/*
* This won't compile. Note the pair<Tf, Ts> where <int, int> is
above. * The errors I get are shown below.
*/
template <typename Tf, typename Ts>
ostream& print_pair_vector(const vector<pair<Tf,Ts> >& vec, ostream&
out, const string& name="v")
{
typedef vector<pair<Tf, Ts> >::const_iterator vpp_itr;

typedef typename vector<pair<Tf, Ts> >::const_iterator vpp_itr;

With the above correction it cleanly compiles with Comeau and MSVC++
2003.
for(vpp_itr it = vec.begin(); it < vec.end(); it++) {
size_t i = it -vec.begin();

In the above line you assume that an iterator is convertible to integral
type. In this particular situation it seems to work (as vector::iterator
is just a raw pointer in the above mentioned implementations), but
generally it's not the case.
out << name << "["<< i << "].first= " << it->first
<< name << "["<< i << "].second=" << it->second
<< endl;
}
return out;
}
 
R

Ron Natalie

bartek said:
In the above line you assume that an iterator is convertible to integral
type. In this particular situation it seems to work (as vector::iterator
is just a raw pointer in the above mentioned implementations), but
generally it's not the case.

No he does not. He subtracts two random access iterators, that yields a
difference value. It's required to work whether the iterator is implemented
with a pointer or some other data type.
 
R

red floyd

Steven T. Hatton said:
Could someone explain this to me?
[major redaction]

/*
* This won't compile. Note the pair<Tf, Ts> where <int, int> is above.
* The errors I get are shown below.
*/
template <typename Tf, typename Ts>
ostream& print_pair_vector(const vector<pair<Tf,Ts> >& vec, ostream& out,
const string& name="v")
{
typedef vector<pair<Tf, Ts> >::const_iterator vpp_itr;
try:
typedef typename vector said:
for(vpp_itr it = vec.begin(); it < vec.end(); it++) {
size_t i = it -vec.begin();
out << name << "["<< i << "].first= " << it->first
<< name << "["<< i << "].second=" << it->second
<< endl;
}
return out;
}

I don't have a C++ compiler handy (I'm on the road), but I think that
the compiler can't be sure that vector<pair<Tf, Ts> >::const_iterator
is a type.
 
S

Steven T. Hatton

bartek said:
Could someone explain this to me?
[..]
typedef vector<pair<Tf, Ts> >::const_iterator vpp_itr;

typedef typename vector<pair<Tf, Ts> >::const_iterator vpp_itr;

With the above correction it cleanly compiles with Comeau and MSVC++
2003.

Man! I tried everything /but/ that. I tried replacing typedef with
typename. Thanks. That works with GCC 3.4.0.
In the above line you assume that an iterator is convertible to integral
type. In this particular situation it seems to work (as vector::iterator
is just a raw pointer in the above mentioned implementations), but
generally it's not the case.

I'm not really sure what to make of the Standard Library's specification of
the difference/distance between iterators. Take a look at this:

/* The following code example is taken from the book
* "The C++ Standard Library - A Tutorial and Reference"
* by Nicolai M. Josuttis, Addison-Wesley, 1999
*
* (C) Copyright Nicolai M. Josuttis 1999.
* Permission to copy, use, modify, sell and distribute this software
* is granted provided this copyright notice appears in all copies.
* This software is provided "as is" without express or implied
* warranty, and with no claim as to its suitability for any purpose.
*/
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;

#include "print.hpp"

#include "assoiter.hpp"

int main()
{
set<int> coll;

// create inserter for coll
// - inconvenient way
asso_insert_iterator<set<int> > iter(coll);

// insert elements with the usual iterator interface
*iter = 1;
iter++;
*iter = 2;
iter++;
*iter = 3;

PRINT_ELEMENTS(coll);

// create inserter for coll and insert elements
// - convenient way
asso_inserter(coll) = 44;
asso_inserter(coll) = 55;

PRINT_ELEMENTS(coll);

// use inserter with an algorithm
int vals[] = { 33, 67, -4, 13, 5, 2 };
copy (vals, vals+(sizeof(vals)/sizeof(vals[0])), // source
asso_inserter(coll)); // destination

PRINT_ELEMENTS(coll);
}
 
B

bartek

No he does not. He subtracts two random access iterators, that
yields a difference value. It's required to work whether the
iterator is implemented with a pointer or some other data type.

Oops... Thanks for pointing that out.
 
B

bartek

bartek said:
Could someone explain this to me?
[..]
typedef vector<pair<Tf, Ts> >::const_iterator vpp_itr;

typedef typename vector<pair<Tf, Ts> >::const_iterator vpp_itr;

With the above correction it cleanly compiles with Comeau and MSVC++
2003.

Man! I tried everything /but/ that. I tried replacing typedef with
typename. Thanks. That works with GCC 3.4.0.
In the above line you assume that an iterator is convertible to
integral type. In this particular situation it seems to work (as
vector::iterator is just a raw pointer in the above mentioned
implementations), but generally it's not the case.

I'm not really sure what to make of the Standard Library's
specification of the difference/distance between iterators. Take a
look at this:

(...)

Yes, of course I was wrong, as pointed out a message before.
Indeed random access iterators can be subtracted from each other, and the
operation results in an integral distance value.

The above code is OK for std::vector, although it's not for std::list or
map. You're specializing on std::vector though, so my remark was missing
the point.

Cheers!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,792
Messages
2,569,639
Members
45,353
Latest member
RogerDoger

Latest Threads

Top