I have a very small header that contains the following code. The code compiles in Windows 7 for 6 months now, but it fails in linux with gcc 4.3.4. I have tried several ways to make it working but unfortunately nothing happens. Does anybody of you have an idea of what could be wrong?
Regards
#ifndef UTILS_H
#define UTILS_H
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <algorithm>
template <class T>
unsigned int findUpperElement(const std::vector<T>& aVec, const T& aTargetValue)
{
typedef std::vector<T>::const_iterator itType;
itType itMatch=upper_bound (aVec.begin(),aVec.end(), aTargetValue);
return std::distance<itType>(aVec.begin(),itMatch);
}
template <class T>
unsigned int findLowerElement(const std::vector<T>& aVec, const T& aTargetValue)
{
typedef std::vector<T>::const_iterator itType;
itType itMatch=lower_bound (aVec.begin(),aVec.end(), aTargetValue);
return std::distance< itType> (aVec.begin(),itMatch);
}
#endif
Here are the errors I get:
./utilslib/Utils.h: In function ‘unsigned int findUpperElement(const std::vector<T, std::allocator<_Tp1> >&, const T&)’:
./utilslib/Utils.h:15: error: too few template-parameter-lists
./utilslib/Utils.h:16: error: ‘itType’ was not declared in this scope
./utilslib/Utils.h:16: error: expected `;' before ‘itMatch’
./utilslib/Utils.h:17: error: ‘itType’ cannot appear in a constant-expression
./utilslib/Utils.h:17: error: ‘itMatch’ was not declared in this scope
./utilslib/Utils.h: In function ‘unsigned int findLowerElement(const std::vector<T, std::allocator<_Tp1> >&, const T&)’:
./utilslib/Utils.h:24: error: too few template-parameter-lists
./utilslib/Utils.h:25: error: ‘itType’ was not declared in this scope
./utilslib/Utils.h:25: error: expected `;' before ‘itMatch’
./utilslib/Utils.h:26: error: ‘itType’ cannot appear in a constant-expression
./utilslib/Utils.h:26: error: ‘itMatch’ was not declared in this scope
Add the typename key word to these lines:
changes to:
Your const_iterator is a nested-dependent-type – a type nested within your template parameter-type which is dependent on it. To understand that distinction you’re supposed to provide the typename key word – to tell the compiler this is the name of a type based on your template type T.
Compilers often don’t implement this quite correctly – some let you get away with more than others.
To give an example of the reason this is required, consider this:
The compiler could interpret this as “I want a pointer to a type T::X called var_name” or it could think “I want to multiply static variable X in class T by the value held in var_name”.
Adding typename like so:
would force it to prefer the first, because it now knows that T::X is a type in this context.