I'm having trouble with templates and dependent types:
namespace Utils
{
void PrintLine(const string& line, int tabLevel = 0);
string getTabs(int tabLevel);
template<class result_t, class Predicate>
set<result_t> findAll_if(typename set<result_t>::iterator begin, set<result_t>::iterator end, Predicate pred) // warning C4346
{
set<result_t> result;
return findAll_if_rec(begin, end, pred, result);
}
}
namespace detail
{
template<class result_t, class Predicate>
set<result_t> findAll_if_rec(set<result_t>::iterator begin, set<result_t>::iterator end, Predicate pred, set<result_t> result)
{
typename set<result_t>::iterator nextResultElem = find_if(begin, end, pred);
if (nextResultElem == end)
{
return result;
}
result.add(*nextResultElem);
return findAll_if_rec(++nextResultElem, end, pred, result);
}
}
Compiler complaints, from the location noted above:
warning C4346: 'std::set<result_t>::iterator' : dependent name is not a type. prefix with 'typename' to indicate a type
error C2061: syntax error : identifier 'iterator'
What am I doing wrong?
There are ways to restrict the types you can use inside a template you write by using specific typedefs inside your template. This will ensure that the compilation of the template specialisation for a type that does not include that particular typedef will fail, so you can selectively support/not support certain types.
A dependent name is a name that depends on the type or the value of a template parameter. For example: template<class T> class U : A<T> { typename T::B x; void f(A<T>& y) { *y++; } }; The dependent names in this example are the base class A<T> , the type name T::B , and the variable y .
A dependent name is essentially a name that depends on a template parameter. A dependent name can be a type, a non-type, or a template parameter. To express that a dependent name stands for a type or a template, you have to use the keywords typename or template .
There are, broadly, two categories of template parameters. template<typename T> (This is more general than marking parameter T as a class or struct or union , as it can also include primitive types like int , bool , etc.) Integral constants, i.e. template<int i> .
Well, the warning says:
dependent name is not a type. prefix with 'typename' to indicate a type
The dependent name (that is, the iterator
in std::set<result_t>::iterator
) is not a type. You need to prefix it with typename
to indicate a type:
typename std::set<result_t>::iterator
So, your declaration should be:
template<class result_t, class Predicate>
set<result_t> findAll_if(typename set<result_t>::iterator begin, typename set<result_t>::iterator end, Predicate pred)
note added typename ^
(and the definition should match the declaration)
You need an additional typename keyword on this line:
set<result_t> findAll_if(typename set<result_t>::iterator begin,
typenameset<result_t>::iterator end, Predicate pred) // warning C4346
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With