public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
From: Thomas Maier <T.Maier@epost.de>
To: gcc-help@gcc.gnu.org
Cc: Thomas Maier <T.Maier@tu-bs.de>
Subject: template problems
Date: Fri, 26 Jul 2002 02:07:00 -0000	[thread overview]
Message-ID: <1027675013.2062.70.camel@marvin> (raw)

[-- Attachment #1: Type: text/plain, Size: 4164 bytes --]

Sorry for reposting, I forgot to attach the file small.cc.

Hi everbody, 

hope this is the right mailing list. I got a problem compiling some C++
code (using "gcc version 2.95.3 20010315 (SuSE)" and also a 3.0 version,
see below).  I do not know if it is valid C++ actually but I guess it
is.  Question is: how can I scope deeper than level one in types used in
templates? :)  Well, if you use a template that gets a container type C
as parameter, you might want to say  "C::value_type some_var;" but in
order to say that you have to use typename:

typename C::value_type some_var;

That's fine.  Now how can I use value_type to "scope one level deeper",
say I want to take the address of some member function of value_type:

void (C::value_type::* some_member_function)();

Just saying

void (typename C::value_type::* some_member_function)();

fails, as does saying

void (typename C::typename value_type::* some_member_function)();

Putting parens just about everywhere did not help, too.  How do I have
to tell g++ to do what I want?  It works in a non-template function:

void f()
{
  {
    map<size_t,string>::mapped_type mt("ext");
    map<size_t,string>::key_type kt(42);
    map<size_t,string>::key_type (map<size_t,string>::mapped_type::* key_method)() const
      = &map<size_t,string>::mapped_type::size;
  }

  {
    typedef map<size_t,string> Cont;
    Cont::mapped_type mt("ext");
    Cont::key_type kt(42);
    Cont::key_type (Cont::mapped_type::* key_method)() const = &Cont::mapped_type::size;
  }
}

The second block is the same as the first one but it uses a typedef to
make things easier to read.  I wrote the first block only to see if the
typedef makes things work.  I attach a small file small.cc that you can
compile.

The problem is:

/*11*/ template <class Container> void
/*12*/ foo(Container& container, void (typename Container::mapped_type::* member_function)())
/*13*/ { }

which gives

g++ -Wall -c small.cc
small.cc:12: parse error before `*'
small.cc:12: `foo' declared as function returning a function


Probably g++ doesn't know that Container::mapped_type is a type.  You
even have to tell it that Container is a type, that's what that typename
is for.  I tried to cheat g++ with writing 

/*16*/ template <class Container, class MappedType = typename Container::mapped_type> void
/*17*/ foo(Container& container, void (MappedType::* member_function)())
/*18*/ { }

but it only said 

small.cc:18: default argument for template parameter in function template `foo(Container &, void (MappedType::*)())'

(Yes, sure it is, doesn't really sound like an error.  Is it one?  In
the Stroustrup there is an example with default arguments so I expected
it to work.) 

I also tried all that with "gcc version 3.0.1 (SuSE)".  Doesn't work. 
Unfortunately I am not able to just download and install the latest gcc
version to see if things work as I only have a very slow dial up
connection (and here in Germany they charge for connection *times*!
pfff...).  And unexperienced as I am that would probably make things
even worse :).  So is this a problem with g++ or with my understanding
of or my way of writing down C++?  And if it is the former, is it fixed
in 3.1 or will it be fixed in 3.2?  And please be so kind and cc any
follow-ups to me as I am not on this list (because of said f!$%&ing slow
modem :). 

Regards and advTHANKSance, Thomas. 



P.S.: Just in case you wonder why the hell I need this: Actually I
wanted to write an assoc_insert_iterator to insert a value into a map
like a back_inserter (gives a back_insert_iterator that) inserts into a
list, for example.  The iterator needs to be parameterized with some X
where it can get the value's key from.  Basically when I write
(simplified pseudo code) 

map<Key, Value> m; 
fill(assoc_inserter(m, X)); 

and fill(assoc_insert_iterator iter) calls iter's operator=, operator=
has to call some method or function "Key X(Value)" that I gave as a
parameter. 

Specifying functions works, see above.  But when I want to pass a method
(exploiting the fact that some classes have some method giving a
key-function) it doesn't, see above.

-- 
Thomas Maier <T.Maier@tu-bs.de>

[-- Attachment #2: small.cc --]
[-- Type: text/x-c, Size: 1023 bytes --]

#include<string>
#include<map>
using namespace std;

// non-member functions work
template <class Container> void
foo(Container& container, void (*function) ())
{ }

// member functions don't
template <class Container> void
foo(Container& container, void (typename Container::mapped_type::* member_function)())
{ }

// also doesn't work
template <class Container, class MappedType = typename Container::mapped_type> void
foo(Container& container, void (MappedType::* member_function)())
{ }

// non-template function using map as container works
void f()
{
  {
    map<size_t,string>::mapped_type mt("ext");
    map<size_t,string>::key_type kt(42);
    map<size_t,string>::key_type (map<size_t,string>::mapped_type::* key_method)() const
      = &map<size_t,string>::mapped_type::size;
  }

  {
    typedef map<size_t,string> Cont;
    Cont::mapped_type mt("ext");
    Cont::key_type kt(42);
    Cont::key_type (Cont::mapped_type::* key_method)() const = &Cont::mapped_type::size;
  }
}

             reply	other threads:[~2002-07-26  9:07 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-07-26  2:07 Thomas Maier [this message]
2002-07-26 11:08 ` Gokhan Kisacikoglu
2002-07-26 15:18   ` Thomas Maier
2002-07-26 16:34     ` Gokhan Kisacikoglu
  -- strict thread matches above, loose matches on Subject: below --
2002-07-26  2:02 Thomas Maier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1027675013.2062.70.camel@marvin \
    --to=t.maier@epost.de \
    --cc=T.Maier@tu-bs.de \
    --cc=gcc-help@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).