0

I made a function find_all which returns a vector of position(iterator) of all position of element xr in a STL container ar. What`s wrong with this code.

template<typename T1, typename T2 = T1::value_type>
auto find_all(const T1& ar, T2 xr)
{
    typedef T1::const_iterator const_iterator;
    vector<const_iterator> it;
    for (auto it2 = ar.cbegin(); it2 != ar.cend(); ++it2)
        if (*it2 == xr)
            it.push_back(it2);
    return it;
}

The code compiles in Visual C++ 2015, but gives following error with gcc compiler: Error :

prog.cpp:3:38: error: need 'typename' before 'T1::value_type' because 'T1' is a dependent scope
  template<typename T1, typename T2 = T1::value_type>
                                      ^
prog.cpp: In function 'auto find_all(const T1&, T2)':
prog.cpp:6:11: error: need 'typename' before 'T1::const_iterator' because 'T1' is a dependent scope
   typedef T1::const_iterator const_iterator;
           ^
prog.cpp:7:10: error: 'const_iterator' was not declared in this scope
   vector<const_iterator> it;
          ^
prog.cpp:7:24: error: template argument 1 is invalid
   vector<const_iterator> it;
                        ^
prog.cpp:7:24: error: template argument 2 is invalid
prog.cpp:7:28: error: invalid type in declaration before ';' token
   vector<const_iterator> it;
                            ^
prog.cpp:10:8: error: request for member 'push_back' in 'it', which is of non-class type 'int'
     it.push_back(it2);
        ^

Ideone Link

I want to simply correct it.

0x6773
  • 1,116
  • 1
  • 14
  • 33
  • 1
    what's the error, or what abnormal behavior are you observing – Arun A S Mar 04 '15 at 13:53
  • 3
    The error tells you exactly how to correct it: *need 'typename' before 'T1::value_type'*. VS is wrong. – chris Mar 04 '15 at 14:00
  • there is already a 'typename' before 'T1::value_type' – 0x6773 Mar 04 '15 at 14:03
  • @mnciitbhu, There needs to be one where the arrow is pointing for the reason stated in the error. The compiler cannot know whether `T1::value_type` is a type or a value, so the decision was to add `typename` when it's a type. – chris Mar 04 '15 at 14:05
  • Also, when you add the `typename`s at the correct locations: The type of a templated `auto` function must be explicitly specified using *trailing return types* (see http://stackoverflow.com/questions/12224325/on-c-trailing-return-type) if the `auto` type depends on one of the template arguments. – dhke Mar 04 '15 at 14:06
  • 4
    @dhke in C++14 you don't have to specify trailing return type if it can be deduced from `return` statement(s). – Anton Savin Mar 04 '15 at 14:24
  • Thanks to all, I got my error! – 0x6773 Mar 04 '15 at 14:28
  • @AntonSavin Thanks for updating me on that. I was erroneously still stuck in C++11. – dhke Mar 04 '15 at 15:55

0 Answers0