Whole Tomato Software Forums
Whole Tomato Software Forums
Main Site | Profile | Register | Active Topics | Members | Search | FAQ
User name:
Password:
Save Password
Forgot your password?

 All Forums
 Visual Assist
 Technical Support
 Syntax highlighting bug : build 1548
 New Topic  Reply to Topic
 Printer Friendly
Author Previous Topic Topic Next Topic  

MrDoomMaster
Tomato Guru

251 Posts

Posted - Feb 26 2007 :  3:36:58 PM  Show Profile  Reply with Quote
Below I'm going to paste a large amount of code. This code contains a class, named ShipyardIterator which is a template class. Inside of this class, as you will see, there's many "typename" keywords spread throughout the file. For example, typename t_type::iterator& iter.

Using the default syntax coloring setup provided by VAX upon a fresh installation, the "iter" keyword in the bolded example above is colored in BLUE. Sometimes, purple (meaning it's getting confused between macros & identifiers or class names). The proper color for the 'iter' keyword should be GRAY.

For a test case, take the entirety of the code I am fixing to paste below and put it in a fresh header file. Open this header file using Visual Studio 2005 Professional (the bug might occur on other IDE's, not sure though.) and ensure you are using the default settings for syntax coloring in Visual Assist. Skim through the document where all of the typename t_type::iterator lines are and look at the color of the corresponding variable. It's definitely bugged!


#ifndef _SHIPYARDITERATOR_HPP_
#define _SHIPYARDITERATOR_HPP_

#include <vector>

#include "PersistedState.hpp"
#include "Shipyard.hpp"


class SkybladeInfo
{
private:
	const Shipyard::Skyblade* m_unpurchased;
	PurchasedShip* m_purchased;

public:
	SkybladeInfo( const Shipyard::Skyblade* unpurchased, PurchasedShip* purchased ) :
		m_unpurchased( unpurchased ),
		m_purchased( purchased )
	{
	}

	friend class Obsoletes;
};

class SkybladeWeaponInfo
{
};


namespace do_not_touch
{
	template< typename t_type >
	class ShipyardIterator
	{
	public:
		enum ClampType
		{
			CLAMP,
			LOOP
		};

	private:
		t_type& m_inventory;
		typename t_type::iterator m_current;
		ClampType m_clampType;

		void AdvanceIterator( typename t_type::iterator& iter, int step )
		{
			// @TODO - RCD
			// Only supports steps of 1 or -1 at the moment
			if( step == 1 || step == -1 )
			{
				switch( m_clampType )
				{
				case CLAMP:
					{
						if( step == 1 )
						{
							if( iter != m_inventory.end() )
							{
								t_type::iterator temp = iter;
								++temp;

								if( temp != m_inventory.end() )
								{
									iter = temp;
								}
							}
						}
						else
						{
							if( iter != m_inventory.begin() )
							{
								--iter;
							}
						}

						break;
					}

					// @TODO - RCD
					// Implement looping
				case LOOP:
					{
						break;
					}
				}
			}
		}

	public:
		ShipyardIterator( t_type& inventory ) :
			m_inventory( inventory ),
			m_clampType( CLAMP )
		{
			m_current = inventory.begin();
		}

		ShipyardIterator( t_type& inventory, typename t_type::iterator& current ) :
			m_inventory( inventory ),
			m_current( current ),
			m_clampType( CLAMP )
		{
		}

		inline void SetClampType( ClampType type )
		{
			m_clampType = type;
		}

		inline typename t_type::value_type& operator*()
		{
			return *m_current;
		}

		inline typename t_type::value_type* operator->()
		{
			return &(*m_current);
		}

		inline const typename t_type::value_type* operator->() const
		{
			return &(*m_current);
		}

		inline ShipyardIterator< t_type >& operator++()
		{
			AdvanceIterator( m_current, 1 );
			return *this;
		}

		inline ShipyardIterator< t_type >& operator--()
		{
			AdvanceIterator( m_current, -1 );
			return *this;
		}
	};
}

typedef std::vector< SkybladeInfo > SkybladeInventory;
typedef std::vector< SkybladeWeaponInfo > SkybladeWeaponInventory;
typedef do_not_touch::ShipyardIterator< SkybladeInventory > SkybladeIterator;
typedef do_not_touch::ShipyardIterator< SkybladeWeaponInventory > SkybladeWeaponIterator;

#endif // _SHIPYARDITERATOR_HPP_

Edited by - MrDoomMaster on Feb 26 2007 3:38:17 PM

feline
Whole Tomato Software

United Kingdom
19020 Posts

Posted - Feb 27 2007 :  12:23:55 PM  Show Profile  Reply with Quote
I am seeing odd colouring here, but to be honest I am confused by this code. Just taking a small piece, specifically:

	template< typename t_type >
	class ShipyardIterator
	{
	public:
		enum ClampType	{ CLAMP, LOOP };

	private:
		t_type& m_inventory;
		typename t_type::iterator m_current;

		// *SNIP*
	};


I have reformatted the enum to save space.

I do some template programming, but not a vast amount, so perhaps there is simply something I am not familiar with going on here, but why is "typename" used on the "m_current" line?

You are using "::iterator", which has to be defined on the type that is used to instantiate this template class, but I would expect the compiler to enforce this restriction at compile time, if "::iterator" is not valid, e.g. because you used the type "int" the code will simply not compile.

zen is the art of being at one with the two'ness
Go to Top of Page

MrDoomMaster
Tomato Guru

251 Posts

Posted - Feb 27 2007 :  12:39:49 PM  Show Profile  Reply with Quote
quote:
Originally posted by feline

I am seeing odd colouring here, but to be honest I am confused by this code. Just taking a small piece, specifically:

	template< typename t_type >
	class ShipyardIterator
	{
	public:
		enum ClampType	{ CLAMP, LOOP };

	private:
		t_type& m_inventory;
		typename t_type::iterator m_current;

		// *SNIP*
	};


I have reformatted the enum to save space.

I do some template programming, but not a vast amount, so perhaps there is simply something I am not familiar with going on here, but why is "typename" used on the "m_current" line?

You are using "::iterator", which has to be defined on the type that is used to instantiate this template class, but I would expect the compiler to enforce this restriction at compile time, if "::iterator" is not valid, e.g. because you used the type "int" the code will simply not compile.



The template class expects either std::vector or std::list, this is by design. If either of these are not specified as the template parameter to the class, the compiler will generate errors due to the "iterator" type not existing in the template type passed in.

I don't know the formal explanation of the situation, all I can tell you is if you're using a typedef inside of an unknown type, you must specify "typename" so that the compiler knows it's a type. For example:

template< typename T >
class Foo
{
    T::someTypeDefine m_myVar;
};


the compiler will throw an error here because the inner type, "someTypeDefine" is unknown. If you add "typename" in front of this line, the compiler will not throw an error because you've told it that it's unknown. It's a bit weird, but definitely a requirement in my situation.

For more information on the specifics of the "typename" keyword, visit:
http://msdn2.microsoft.com/en-us/library/8y88s595(VS.80).aspx
Go to Top of Page

holedigger
Whole Tomato Software

145 Posts

Posted - Feb 27 2007 :  1:07:19 PM  Show Profile  Reply with Quote
C++ cannot know if t_type::iterator is a type or not until the template is instantiated. It assumes it is NOT a type unless explicitly told it is. Here's an example from Scott Meyers' "Effective C++" book:

template<typename C>
void print2nd(const C& container)
{
C::const_iterator * x;
}

Either x is a pointer to a C::const_iterator, or instead the statement is a multiplication between two variables. C++ actually assumes the multiplication. To fix it, you need "typename C::const_iterator * x;"

Whole Tomato Software
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
19020 Posts

Posted - Feb 27 2007 :  1:54:36 PM  Show Profile  Reply with Quote
*ah* this makes sense, thank you for the explanation.

case=5279

zen is the art of being at one with the two'ness
Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
© 2023 Whole Tomato Software, LLC Go To Top Of Page
Snitz Forums 2000