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


    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;
    51: util::Regex criteria;
    52: const int cflags(options::eregex() ?
    53: util::Regex::extended|util::Regex::icase : util::Regex::icase);
    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);
    65: /* it's valid, so compile regex */
    66: criteria.assign(f->second, cflags);
    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;
    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?)

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

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

    Any pointers in the right direction?

    Much appreciated,
    Aaron Walker, Oct 1, 2005
    1. Advertisements

  2. 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;

    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;

    John Harrison, Oct 1, 2005
    1. Advertisements

  3. Please don't post line numbers. Just add a comment to the line you
    want to mark.
    Add 'typename' at the beginning:


    Victor Bazarov, Oct 1, 2005
  4. Aaron Walker

    Aaron Walker Guest


    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".


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

    Aaron Walker Guest

    Ah, ok apologies. I figured it'd make it easier on whoever was trying to help.
    Will keep in mind next time.
    Yep, that does it.

    Aaron Walker, Oct 1, 2005
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.