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

Templates and typedef

P: n/a
Although I've got over most of my template-related problems, I'm
having trouble when I started to use default template parameters.
For template type T, I've typedef'd this as object_type and then
typedef'd std::vector<T> menu_list. This doesn't seem to
work though:

40 template<typename W>
41 class ObjectOptionMenuDescribeObject
42 {
43 public:
44 std::string operator () (const W& object)
45 {
46 std::ostringstream desc;
47 desc << object;
48 return desc.str();
49 }
50 };
51
52 template<typename T, typename D = ObjectOptionMenuDescribeObject<T> >
53 class ObjectOptionMenu : public Gtk::OptionMenu
54 {
55 public:
56 typedef T object_type;
57 typedef D description_func;
58
59 typedef std::vector<T> menu_list;
60
61 ObjectOptionMenu(const menu_list& list):
62 m_desc(),
63 m_options()
64 {
65 menu_list::const_iterator cur;
66 for (cur = list.begin();
67 cur != list.end();
68 ++cur)
69 add_item(*cur);
70 }
[...]
172 description_func m_desc;
173 menu_list m_options;
174
175 }; // class OptionMenu

[Gtk::OptionMenu is a GUI menu widget.]

When I try to compile this (just included into an empty .cc file) I
get this:

$ g++ [lots of -I options] -c test.cc
In file included from test.cc:1:
objectoptionmenu.h: In constructor `Gtkmm::ObjectOptionMenu<T,
D>::ObjectOptionMenu(const std::vector<T, std::allocator<_CharT> >&)':
objectoptionmenu.h:65: error: syntax error before `;' token

It looks like menu_list isn't defined, which gives the parse error.
This doesn't change if I change menu_list to std::vector<T>, so I
think there may be something wrong with the template definition, but I
can't see what.
When I include the same header in a real source file with lots of
other headers included as well, the error is even stranger:

In file included from posreturnsdialog.h:19,
from epicpos.cc:24:
objectoptionmenu.h: In constructor `Gtkmm::ObjectOptionMenu<T,
D>::ObjectOptionMenu(const std::vector<_Row, std::allocator<_CharT> >&)':
objectoptionmenu.h:65: error: syntax error before `;' token

Where on earth have _Row and std::allocator<_CharT> appeared from?
[_Row is a template parameter in another header, but it's not
referenced at all.] How can another unrelated template parameter
"pollute" my template? (Especially since I've not yet instantiated
it.)
Possibly related: what is the scope of the template parameter name?
Does it have to be unique to just the enclosed class/function, or all
templates declared within that scope?
Many thanks,
Roger

--
Roger Leigh

Printing on GNU/Linux? http://gimp-print.sourceforge.net/
GPG Public Key: 0x25BFB848. Please sign and encrypt your mail.
Jul 22 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Roger Leigh wrote:
Although I've got over most of my template-related problems, I'm
having trouble when I started to use default template parameters.
For template type T, I've typedef'd this as object_type and then
typedef'd std::vector<T> menu_list. This doesn't seem to
work though:

40 template<typename W>
41 class ObjectOptionMenuDescribeObject
42 {
43 public:
44 std::string operator () (const W& object)
45 {
46 std::ostringstream desc;
47 desc << object;
48 return desc.str();
49 }
50 };
51
52 template<typename T, typename D = ObjectOptionMenuDescribeObject<T> >
53 class ObjectOptionMenu : public Gtk::OptionMenu
54 {
55 public:
56 typedef T object_type;
57 typedef D description_func;
58
59 typedef std::vector<T> menu_list;
60
61 ObjectOptionMenu(const menu_list& list):
62 m_desc(),
63 m_options()
64 {
65 menu_list::const_iterator cur;
typename menu_list::const_iterator cur;
66 for (cur = list.begin();
67 cur != list.end();
68 ++cur)
69 add_item(*cur);
70 }
[...]
172 description_func m_desc;
173 menu_list m_options;
174
175 }; // class OptionMenu

[Gtk::OptionMenu is a GUI menu widget.]

When I try to compile this (just included into an empty .cc file) I
get this:

$ g++ [lots of -I options] -c test.cc
In file included from test.cc:1:
objectoptionmenu.h: In constructor `Gtkmm::ObjectOptionMenu<T,
D>::ObjectOptionMenu(const std::vector<T, std::allocator<_CharT> >&)':
objectoptionmenu.h:65: error: syntax error before `;' token

It looks like menu_list isn't defined, which gives the parse error.
This doesn't change if I change menu_list to std::vector<T>, so I
think there may be something wrong with the template definition, but I
can't see what.
When I include the same header in a real source file with lots of
other headers included as well, the error is even stranger:

In file included from posreturnsdialog.h:19,
from epicpos.cc:24:
objectoptionmenu.h: In constructor `Gtkmm::ObjectOptionMenu<T,
D>::ObjectOptionMenu(const std::vector<_Row, std::allocator<_CharT> >&)':
objectoptionmenu.h:65: error: syntax error before `;' token

Where on earth have _Row and std::allocator<_CharT> appeared from?
[_Row is a template parameter in another header, but it's not
referenced at all.] How can another unrelated template parameter
"pollute" my template? (Especially since I've not yet instantiated
it.)
Possibly related: what is the scope of the template parameter name?
Does it have to be unique to just the enclosed class/function, or all
templates declared within that scope?
Many thanks,
Roger


Jul 22 '05 #2

P: n/a
Jeffrey Schwab <je******@comcast.net> writes:
Roger Leigh wrote:
Although I've got over most of my template-related problems, I'm
having trouble when I started to use default template parameters.
For template type T, I've typedef'd this as object_type and then
typedef'd std::vector<T> menu_list. This doesn't seem to
work though:
40 template<typename W>
41 class ObjectOptionMenuDescribeObject
42 {
43 public:
44 std::string operator () (const W& object)
45 {
46 std::ostringstream desc;
47 desc << object;
48 return desc.str();
49 }
50 };
51
52 template<typename T, typename D = ObjectOptionMenuDescribeObject<T> >
53 class ObjectOptionMenu : public Gtk::OptionMenu
54 {
55 public:
56 typedef T object_type;
57 typedef D description_func;
58
59 typedef std::vector<T> menu_list;
60
61 ObjectOptionMenu(const menu_list& list):
62 m_desc(),
63 m_options()
64 {
65 menu_list::const_iterator cur;


typename menu_list::const_iterator cur;


Thanks, that works just fine!

Is it possible to declare this as a type, rather than using typename
each time?
I tried putting

typename menu_list::const_iterator;

just after the typedefs, but that doesn't work. I'd rather the users
of the class didn't need to use typename--is there any way to achieve
this?
Thanks again,
Roger

--
Roger Leigh

Printing on GNU/Linux? http://gimp-print.sourceforge.net/
GPG Public Key: 0x25BFB848. Please sign and encrypt your mail.
Jul 22 '05 #3

P: n/a
On Thu, 18 Dec 2003 16:51:34 +0000, Roger Leigh
<${******@invalid.whinlatter.uklinux.net.invalid > wrote:
Jeffrey Schwab <je******@comcast.net> writes:
Roger Leigh wrote:
Although I've got over most of my template-related problems, I'm
having trouble when I started to use default template parameters.
For template type T, I've typedef'd this as object_type and then
typedef'd std::vector<T> menu_list. This doesn't seem to
work though:
40 template<typename W>
41 class ObjectOptionMenuDescribeObject
42 {
43 public:
44 std::string operator () (const W& object)
45 {
46 std::ostringstream desc;
47 desc << object;
48 return desc.str();
49 }
50 };
51
52 template<typename T, typename D = ObjectOptionMenuDescribeObject<T> >
53 class ObjectOptionMenu : public Gtk::OptionMenu
54 {
55 public:
56 typedef T object_type;
57 typedef D description_func;
58
59 typedef std::vector<T> menu_list;
60
61 ObjectOptionMenu(const menu_list& list):
62 m_desc(),
63 m_options()
64 {
65 menu_list::const_iterator cur;
typename menu_list::const_iterator cur;


Thanks, that works just fine!

Is it possible to declare this as a type, rather than using typename
each time?


You only have to use typename when using a member of a dependent type
that is also a type. So it only applies to code inside a template
definition. e.g. this is fine

ObjectOptionMenu<int>::menu_list::const_iterator i;
I tried putting

typename menu_list::const_iterator;

just after the typedefs, but that doesn't work.
You could add

typedef typename menu_list::const_iterator const_iterator;

and then you can use "const_iterator" instead of "typename
menu_list::const_iterator".
I'd rather the usersof the class didn't need to use typename--is there any way to achieve
this?


The users of which class? How do they use it?

Tom

C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #4

P: n/a
Roger Leigh <${******@invalid.whinlatter.uklinux.net.invalid > wrote in message news:<87************@wrynose.whinlatter.uklinux.ne t>...
[snip]
52 template<typename T, typename D = ObjectOptionMenuDescribeObject<T> >
53 class ObjectOptionMenu : public Gtk::OptionMenu
54 {
55 public:
56 typedef T object_type;
57 typedef D description_func;
58
59 typedef std::vector<T> menu_list;

[snip]

I think you will like the new Gtk::ComboBox in gtkmm 2.4 which seems
to do what you want (any data types), with a model/view separation as
well.
Jul 22 '05 #5

P: n/a
tom_usenet <to********@hotmail.com> writes:
On Thu, 18 Dec 2003 16:51:34 +0000, Roger Leigh
<${******@invalid.whinlatter.uklinux.net.invalid > wrote:
Jeffrey Schwab <je******@comcast.net> writes:

typename menu_list::const_iterator cur;


Thanks, that works just fine!

Is it possible to declare this as a type, rather than using typename
each time?


You only have to use typename when using a member of a dependent type
that is also a type. So it only applies to code inside a template
definition. e.g. this is fine

ObjectOptionMenu<int>::menu_list::const_iterator i;


I see.
I tried putting

typename menu_list::const_iterator;

just after the typedefs, but that doesn't work. I'd rather the users of the class didn't need to use typename--is
there any way to achieve this?


The users of which class? How do they use it?


I wasn't aware of exactly how typename worked. This question is
wrong--I meant code using the ObjectOptionMenu<> class, but since they
don't need to use typename anyway, it's a non-issue.
For anyone else having problems with templates (and default
parameters), my working code follows:
// object-based option menu -*- C++ -*-
// $Id: objectoptionmenu.h,v 1.2 2003/12/14 16:14:54 roger Exp $
//
// Copyright (C) 2003 Roger Leigh.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////

#ifndef GTKMM_RLEXTRA_OBJECTOPTIONMENU_H
#define GTKMM_RLEXTRA_OBJECTOPTIONMENU_H

#include <cassert>
#include <iostream>
#include <map>
#include <sstream>
#include <vector>

#include <gtkmm/optionmenu.h>
#include <gtkmm/menu.h>

#include <libglademm/xml.h>

namespace Gtkmm
{
template<typename T>
class ObjectOptionMenuDescribeObject
{
public:
typedef T object_type;

std::string operator () (const object_type& object) const
{
std::ostringstream desc;
desc << object;
return desc.str();
}
};

template<typename T>
class ObjectOptionMenuItem : public Gtk::MenuItem
{
public:
typedef T object_type;

ObjectOptionMenuItem(const object_type& object,
const Glib::ustring& label):
Gtk::MenuItem(label),
m_object(object)
{}

virtual ~ObjectOptionMenuItem()
{}

const object_type& get_object() const
{
return m_object;
}

private:
object_type m_object;
};

template<typename T, typename D = ObjectOptionMenuDescribeObject<T> >
class ObjectOptionMenu : public Gtk::OptionMenu
{
public:
typedef T object_type;
typedef D description_func;

typedef std::vector<object_type> menu_list;

ObjectOptionMenu():
describe_object(),
m_options(),
m_menu()
{
}

ObjectOptionMenu(const menu_list& list):
describe_object(),
m_options(),
m_menu()
{
add_menu(list);
}

/**
* Constructor for initialisation from a Glade interface description.
* @param cobject the GTK+ C object.
* @param xml_interface the Glade XML interface.
*/
explicit ObjectOptionMenu(BaseObjectType* cobject,
const Glib::RefPtr<Gnome::Glade::Xml>& xml_interface):
describe_object(),
m_options(),
m_menu()
{}

virtual ~ObjectOptionMenu()
{}

void set_menu(const menu_list& list)
{
std::cerr << "ObjectOptionMenu::add_menu()" << std::endl;

remove_menu();

for (typename menu_list::const_iterator cur = list.begin();
cur != list.end();
++cur)
{
m_options.push_back(*cur);
Gtk::MenuItem *menu_item =
manage(new ObjectOptionMenuItem<object_type>(*cur, describe_object(*cur)));
m_menu.append(*menu_item);
}

Gtk::OptionMenu::set_menu(m_menu);
Gtk::OptionMenu::set_history(0);
}

void remove_menu()
{
m_options.clear();
Gtk::OptionMenu::remove_menu();
m_menu.items().clear();
}

const object_type* get_history() const
{
int selected = Gtk::OptionMenu::get_history();

const Gtk::MenuItem& menu_item = get_menu()->items()[selected];

const Gtk::MenuItem* menu_item_ptr = &menu_item;

const ObjectOptionMenuItem<object_type> *object_menu_item =
dynamic_cast<const ObjectOptionMenuItem<object_type>* >(menu_item_ptr);

if (object_menu_item != NULL)
return &object_menu_item->get_object();

return NULL;
}

void set_history(const object_type& object)
{
Gtk::MenuShell::MenuList& menu_list = get_menu()->items();
Gtk::MenuShell::MenuList::size_type size = menu_list.size();
for (Gtk::MenuShell::MenuList::size_type cur = 0;
cur < size;
++cur)
{
const Gtk::MenuItem& menu_item = menu_list[cur];
const Gtk::MenuItem* menu_item_ptr = &menu_item;

const ObjectOptionMenuItem<object_type> *object_menu_item =
dynamic_cast<const ObjectOptionMenuItem<object_type>* >(menu_item_ptr);

if (object_menu_item != NULL)
{
if (object == object_menu_item->get_object())
{
Gtk::OptionMenu::set_history(cur);
return;
}
}
}
Gtk::OptionMenu::set_history(0);
}

void on_changed()
{
std::cerr << "OptionMenu::on_changed()" << std::endl;
std::cerr << " There are " << m_menu.items().size() << " items" << std::endl;
if (get_history() != NULL)
std::cerr << " Currently selected: " << describe_object(*get_history()) << std::endl;
else
std::cerr << " Nothing currently selected" << std::endl;
}

protected:
description_func describe_object;
menu_list m_options;
Gtk::Menu m_menu;

}; // class OptionMenu

}; // namespace Gtkmm
#endif // GTKMM_RLEXTRA_OBJECTOPTIONMENU_H
--
Roger Leigh

Printing on GNU/Linux? http://gimp-print.sourceforge.net/
GPG Public Key: 0x25BFB848. Please sign and encrypt your mail.
Jul 22 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.