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

Discussion in 'C++' started by Aaron Walker, Oct 1, 2005.

  1. Aaron Walker

    Aaron Walker Guest

    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
     
    Aaron Walker, Oct 1, 2005
    #1
    1. Advertising

  2. Re: Can't figure out syntax error with templates/member functionpointers

    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
     
    John Harrison, Oct 1, 2005
    #2
    1. Advertising

  3. 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
     
    Victor Bazarov, Oct 1, 2005
    #3
  4. Aaron Walker

    Aaron Walker Guest

    Re: Can't figure out syntax error with templates/member functionpointers

    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
     
    Aaron Walker, Oct 1, 2005
    #4
  5. Aaron Walker

    Aaron Walker Guest

    Re: Can't figure out syntax error with templates/member functionpointers

    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
     
    Aaron Walker, Oct 1, 2005
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. python newbie

    can't figure out syntax prob

    python newbie, Nov 22, 2003, in forum: Python
    Replies:
    2
    Views:
    307
    python newbie
    Nov 22, 2003
  2. recover
    Replies:
    2
    Views:
    862
    recover
    Jul 25, 2006
  3. mieskola
    Replies:
    1
    Views:
    330
    mlimber
    Aug 16, 2006
  4. John
    Replies:
    2
    Views:
    363
  5. Nephi Immortal
    Replies:
    7
    Views:
    284
Loading...

Share This Page