The problem with templates ('typename' as not a parameter to the template function)

I actually have a problem compiling some library with the Intel compiler.

The same library was compiled with g ++.

The problem is caused by patterns. What I would like to understand is the expression **typename** as not a parameter to the template function and a variable declaration inside the function body

Example:

 void func(typename sometype){.. ... typename some_other_type; .. } 

Compiling such code leads to the following errors (intel), (gcc does not require): I have the following errors.

 ../../../libs/log/src/attribute_set.cpp(415): error: no operator "!=" matches these operands operand types are: boost::log_st::basic_attribute_set<wchar_t>::iter<'\000'> != boost::log_st::basic_attribute_set<wchar_t>::iter<'\000'> while (begin != end) ^ detected during instantiation of "void boost::log_st::basic_attribute_set<CharT>::erase(boost::log_st::basic_attribute_set<CharT>::iter<'\000'>, boost::log_st::basic_attribute_set<CharT>::iter<'\000'>) [with CharT=wchar_t]" at line 438 ../../../boost/log/attributes/attribute_set.hpp(115): error: no operator "!=" matches these operands operand types are: boost::log_st::basic_attribute_set<wchar_t>::iter<'\000'> != boost::log_st::basic_attribute_set<wchar_t>::iter<'\000'> if (it != m_pContainer->end()) 

What I would like to understand is the use of typename inside the body of functions, declaration of parameters.

eg:.

 template< typename CharT > struct basic_attribute_values_view< CharT >::implementation { public: .. .. void adopt_nodes( **typename attribu**te_set_type::const_iterator& it, **typename attribut**e_set_type::const_iterator end) { for (; it != end; ++it) push_back(it->first, it->second.get()); } 

in another file:

 template< typename CharT > class basic_attribute_set { friend class basic_attribute_values_view< CharT >; //! Self type typedef basic_attribute_set< CharT > this_type; public: //! Character type typedef CharT char_type; //! String type typedef std::basic_string< char_type > string_type; //! Key type typedef basic_slim_string< char_type > key_type; //! Mapped attribute type typedef shared_ptr< attribute > mapped_type; //! Value type typedef std::pair< const key_type, mapped_type > value_type; //! Allocator type typedef std::allocator< value_type > allocator_type; //! Reference type **typedef typename allocator_type::reference reference;** 
+4
c ++ boost generic-programming
Oct 21 '09 at 12:25
source share
3 answers

You need to use typename for the so-called "dependent types". These are types that depend on the template argument and are unknown until the template is created. This is probably best explained with an example:

 struct some_foo { typedef int bar; }; template< typename Foo > struct baz { typedef Foo::bar barbar; // wrong, shouldn't compile barbar f(); // would be fine if barbar were a type // more stuff... }; 

This typedef definition of barbar is one that requires typename so that the compiler can check the template for blatant syntax errors before it is created with a particular type. The reason is that when the compiler sees the template for the first time (when it has not yet been created with the specific parameters of the template), the compiler does not know if the type Foo::bar type. As far as I know, I could intend baz create instances with types like this

 struct some_other_foo { static int bar; }; 

in this case, Foo::bar will refer to the object, not the type, and the definition of baz::bar will be syntactically meaningless. Without knowing whether Foo::bar type, the compiler cannot check anything in baz , directly or indirectly using barbar for even the barbar typos until baz is created. Using the correct typename , baz looks like this:

 template< typename Foo > struct baz { typedef typename Foo::bar barbar; barbar f(); // more stuff... }; 

Now the compiler at least knows that Foo::bar must be a type name, which makes barbar a type name. So the declaration of f() also syntactic.

By the way, there is a similar problem with templates instead of types:

 template< typename Foo > struct baz { Foo::bar<Foo> create_wrgl(); // wrong, shouldn't compile }; 

When the compiler "sees" Foo::bar , it does not know what it is, so bar<Foo may just be a comparison, leaving the compiler confused about the final > . Here you also need to give the compiler a hint that Foo::bar should be the name of the template:

 template< typename Foo > struct baz { Foo::template bar<Foo> create_wrgl(); }; 

Beware: especially Visual C ++ still does not implement the correct two-phase search (essentially: it does not check patterns until they are created). Therefore, it often accepts erroneous code that skips typename or template .

+12
Oct 21 '09 at 12:43
source share

The point of the typename keyword is to tell the compiler that something is typename, in situations where this is not obvious. Take this example:

 template<typename T> void f() { T::foo * x; } 

Is T::foo type, that is, we declare a pointer or put a variable T::foo , and we do the multiplication?

Since the compiler has no idea that T may be while he is reading the template, he does not know which of the two cases is correct.

The standard dictates that the compiler should accept the latter case and interpret only T::foo as typename if it is preceded by the typename keyword, for example:

 template<typename T> void f() { typename T::foo* x; //Definitely a pointer. } 
+3
Oct 21 '09 at 12:34
source share

According to your code:

 void func(typename sometype) { .....typename some_other_type; .. } 

If the above code is not part of the template, it cannot be compiled using g ++, unless the old version is g ++.

As my experience, FC9 or GNU C / ++ version 4.2x report this as an error, it will complain:

 typename only can be used in template code 

while FC8 or GNU C / ++ 4.1x cannot.

Cm.

 http://code.google.com/p/effocore/source/browse/trunk/devel/effo/codebase/addons/inl/include/ringed_inl.h and http://code.google.com/p/effocore/source/browse/trunk/devel/effo/codebase/addons/inl/include/cont_inl.h 

for more examples of patterns and types.

0
21 Oct '09 at 12:51
source share



All Articles