By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,453 Members | 3,225 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,453 IT Pros & Developers. It's quick & easy.

Can't figure out syntax error with templates/member function pointers

P: n/a
Greetings,

I'm attempting to write my first *real* template function that also deals with
a map of strings to member function pointers that is making the syntax a little
tricky to get right.

The function in question:

36: template <typename Container,
37: typename OutputIterator,
38: typename UnaryOp>
39: void
40: transform_fields_into_matches(
41: typename Container::const_iterator first,
42: typename Container::const_iterator last,
43: OutputIterator result,
44: const fields_type& fields,
45: const std::map<std::string,
46: const std::string& (Container::value_type::*)(void) const > & fm,
47: UnaryOp op)
48: {
49: typedef const std::string& (Container::value_type::*mfp)(void) const;
50:
51: util::Regex criteria;
52: const int cflags(options::eregex() ?
53: util::Regex::extended|util::Regex::icase : util::Regex::icase);
54:
55: for (; first != last ; ++first)
56: {
57: fields_type::const_iterator f;
58: for (f = fields.begin() ; f != fields.end() ; ++f)
59: {
60: /* check if field is valid */
61: std::map<std::string, mfp>::const_iterator i = fm.find(f->first);
62: if (i == fm.end())
63: throw InvalidField(f->first);
64:
65: /* it's valid, so compile regex */
66: criteria.assign(f->second, cflags);
67:
68: /* compare criteria against the return value of the
69: * Container::value_type member function mapped to
70: * this field. */
71: const typename Container::value_type& v(*first);
72: if (criteria != (v.*(i->second))())
73: break;
74:
75: /* we're on the last field, meaning all fields that came before
76: * it also matched, so save it finally. */
77: if ((f+1) == fields.end())
78: *result++ = op(*first);
79: }
80: }
81: }

For some reason I can't figure out, the compile keeps bailing on line 61 with:
"error: expected ';' before i".

I'm thinking maybe it has something to do with the lack of 'typename' when
using Container::value_type in the function pointer, but adding that seems to
cause another problem (maybe I'm not putting it in the right place?)

using:
typedef const std::string& (typename Container::value_type::*mfp)(void) const;

causes:
error: expected unqualified-id before ‘typename’
error: expected `)' before ‘typename’
error: expected initializer before ‘typename’

Any pointers in the right direction?

Much appreciated,
Aaron
Oct 1 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
Aaron Walker wrote:
Greetings,

I'm attempting to write my first *real* template function that also deals with
a map of strings to member function pointers that is making the syntax a little
tricky to get right.

The function in question:

36: template <typename Container,
37: typename OutputIterator,
38: typename UnaryOp>
39: void
40: transform_fields_into_matches(
41: typename Container::const_iterator first,
42: typename Container::const_iterator last,
43: OutputIterator result,
44: const fields_type& fields,
45: const std::map<std::string,
46: const std::string& (Container::value_type::*)(void) const > & fm,
47: UnaryOp op)
48: {
[snip]

Any pointers in the right direction?


well I'm not sure of your actual question because that is wildly complex
syntax you have. But I can see that you are heading in the wrong direction.

Look at this simple code

#include <vector>

template <typename Container>
void f(typename Container::iterator i)
{
typename Container::value_type v;
}

int main()
{
std::vector<int> i;
f(i.begin());
}

It fails to compile. The reason is that the compiler cannot work out
what Container is. The rules of C++ prevent the compiler from deducing
the template argument when the function argument type is of the form
typename T::m.

If you ever got your code to compile you would face this issue and there
isn't a solution (other than specifying the template arguments explcitily).

To pass iterators to a template function you should do the following and
use iterator_traits if you want the value type.

#include <vector>

template <typename I>
void f(I i)
{
std::iterator_traits<I>::value_type v;
}

int main()
{
std::vector<int> i;
f(i.begin());
}

john
Oct 1 '05 #2

P: n/a
Aaron Walker wrote:
Greetings,

I'm attempting to write my first *real* template function that also
deals with
a map of strings to member function pointers that is making the
syntax a little tricky to get right.

The function in question:
[...]
61: std::map<std::string, mfp>::const_iterator i =
fm.find(f->first);
62: if (i == fm.end())
Please don't post line numbers. Just add a comment to the line you
want to mark.
For some reason I can't figure out, the compile keeps bailing on line
61 with: "error: expected ';' before i".
Add 'typename' at the beginning:

typename std::map<...>::const_iterator i = ...
I'm thinking maybe it has something to do with the lack of 'typename'
when
using Container::value_type in the function pointer, but adding that
seems to cause another problem (maybe I'm not putting it in the right
place?)


Probably.

V
Oct 1 '05 #3

P: n/a
John Harrison wrote:
Aaron Walker wrote:
Greetings,

I'm attempting to write my first *real* template function that also
deals with
a map of strings to member function pointers that is making the syntax
a little
tricky to get right.

The function in question:

36: template <typename Container,
37: typename OutputIterator,
38: typename UnaryOp>
39: void
40: transform_fields_into_matches(
41: typename Container::const_iterator first,
42: typename Container::const_iterator last,
43: OutputIterator result,
44: const fields_type& fields,
45: const std::map<std::string,
46: const std::string& (Container::value_type::*)(void)
const > & fm,
47: UnaryOp op)
48: {

[snip]

Any pointers in the right direction?


well I'm not sure of your actual question because that is wildly complex
syntax you have. But I can see that you are heading in the wrong direction.


<snip>

My question was why would this:

49: typedef const std::string& (Container::value_type::*mfp)(void) const;
....
61: std::map<std::string, mfp>::const_iterator i = fm.find(f->first);

produce this compile failure:

61: "error: expected ';' before i".


It fails to compile. The reason is that the compiler cannot work out
what Container is. The rules of C++ prevent the compiler from deducing
the template argument when the function argument type is of the form
typename T::m.

If you ever got your code to compile you would face this issue and there
isn't a solution (other than specifying the template arguments explcitily).

To pass iterators to a template function you should do the following and
use iterator_traits if you want the value type.


<snip>

I was wondering if it'd be able to deduce the container type, but hadn't gotten
that far due to the syntax error. I didn't realize I could get the value_type
from iterator_traits.

Thanks for helping with what would probably have been my next problem :)

Aaron
Oct 1 '05 #4

P: n/a
Victor Bazarov wrote:

Please don't post line numbers. Just add a comment to the line you
want to mark.

Ah, ok apologies. I figured it'd make it easier on whoever was trying to help.
Will keep in mind next time.
For some reason I can't figure out, the compile keeps bailing on line
61 with: "error: expected ';' before i".

Add 'typename' at the beginning:

typename std::map<...>::const_iterator i = ...


Yep, that does it.

Thanks,
Aaron
Oct 1 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.