C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Const problem when instantiating function template

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards
View previous topic :: View next topic  
Author Message
Stefan Heinzmann
Guest





PostPosted: Mon May 17, 2004 5:18 pm    Post subject: Const problem when instantiating function template Reply with quote



Hi all,

I have disagreement between two compilers when deducing template
parameters on instantiation of a function template and would like to
know which compiler is right. The problem is related to a const
qualification. Here's the code:

#include <algorithm>

// =============================================================
// Generic map element declarations.
// -------------------------------------------------------------

template<typename Elem> struct map_element_traits;

template<typename Elem> inline
const typename map_element_traits<Elem>::key_type&
key(const Elem& element)
{
return map_element_traits<Elem>::key(element);
}

template<typename Elem> inline
const typename map_element_traits<Elem>::mapped_type&
mapped_value(const Elem& element)
{
return map_element_traits<Elem>::mapped_value(element);
}

template<typename Elem>
struct key_value_compare
{
typedef typename map_element_traits<Elem>::value_type vtype;

bool operator()(const vtype& a, const vtype& b) const
{
return map_element_traits<Elem>::key(a)
< map_element_traits }
};

// =============================================================
// Generic map declarations.
// -------------------------------------------------------------

template<typename Map> struct map_traits;

template<typename Map> inline
typename map_traits<Map>::const_iterator
begin(Map const& map)
{
return map_traits<Map>::begin(map);
}

template<typename Map> inline
typename map_traits<Map>::const_iterator
end(Map const& map)
{
return map_traits<Map>::end(map);
}

template<typename Map> inline
typename map_traits<Map>::const_iterator
find(Map const& m, typename map_traits<Map>::key_type const& k)
{
return map_traits<Map>::find(m, k);
}

template<typename Map>
typename map_traits<Map>::mapped_type const&
lookup( Map const& map,
typename map_traits<Map>::key_type const& key,
typename map_traits<Map>::mapped_type const& def_value)
{
typename map_traits<Map>::const_iterator i = find(map, key);
return (i == end(map)) ? def_value : mapped_value(*i);
}

// =============================================================
// Types for lookup tables stored in ROM.
// -------------------------------------------------------------

template<typename Key, typename Val>
struct Pair
{
Key key;
Val val;
};

template<typename Key, typename Val>
struct map_element_traits< Pair
{
typedef Pair<Key,Val> value_type;
typedef Key key_type;
typedef Val mapped_type;

static const key_type& key(const value_type& e)
{ return e.key; }
static const mapped_type& mapped_value(const value_type& e)
{ return e.val; }
};

template<typename Key, typename Val, unsigned n>
struct map_traits< Pair //### const or not?
{
typedef Key key_type;
typedef Val mapped_type;
typedef Pair<Key,Val> value_type;
typedef const value_type* const_iterator;

static const_iterator begin(const value_type (&map)[n])
{ return &map[0]; }
static const_iterator end (const value_type (&map)[n])
{ return &map[n]; }

static const_iterator find(const value_type (&map)[n]
,const key_type& k)
{
value_type elem = { k };
const_iterator i = std::lower_bound(begin(map), end(map)
, elem, key_value_compare<value_type>());
return (i == end(map) || key(*i) != k) ? end(map) : i;
}
};

// =============================================================
// Usage test
// -------------------------------------------------------------

const Pair<int, const char*> table[] =
{
{ 0, "Ok" },
{ 6, "Minor glitch in self-destruction module" },
{ 13, "Error logging printer out of paper" },
{ 101, "Emergency cooling system inoperable" },
{ 2349, "Dangerous substances released" },
{ 32767, "Game over, you lost" }
};

int main()
{
const char *result = lookup(table, 5, "not found");
}


The problem is related to the struct map_traits. GCC 3.3 compiles the
code as shown, whereas VC++ 7.1 needs the marked line to be changed to this:

struct map_traits< const Pair //### const or not?

Obviously, the two compilers disagree when deducing the type of the
first argument to the lookup function template. Which one is right?

--
Cheers
Stefan

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Back to top
tom_usenet
Guest





PostPosted: Fri May 21, 2004 4:57 am    Post subject: Re: Const problem when instantiating function template Reply with quote



On Mon, 17 May 2004 17:18:12 +0000 (UTC), [email]stefan_heinzmann (AT) yahoo (DOT) com[/email]
(Stefan Heinzmann) wrote:

Quote:
Hi all,

I have disagreement between two compilers when deducing template
parameters on instantiation of a function template and would like to
know which compiler is right. The problem is related to a const
qualification. Here's the code:

[SNIP]

Here's simplified version:

template <class T>
void f(T const& t);

int main()
{
int const array[1] = {0};
f(array);

//What shoud T be deduced as in the call to f?
}

Well, during TAD (template argument deduction), P is the parameter
type (const T&) and A is the argument type (int const[1]). A is not
transformed since P is a reference type, but P is transformed to "T
const" (the referenced type is used, see 14.8.2.1/2).

So, we need to choose a T such that T const == int const[1]. Now, both
T = int const[1] and T = int[1] make the above true, since const
qualifying an array is equivalent to const qualifying the elements.

Comeau and VC 7.1 deduce T = int const[1] and GCC 3.3 deduces T =
int[1]. I really can't see anything in the standard to say which is
right, so perhaps this is a defect in the standard. Defect report
anyone?

Tom
--
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.