2

The following function

#include <memory>

template<typename T>
std::shared_ptr<typename T> Tail(const std::shared_ptr<typename T>& cont, size_t n)
{
   const auto size(std::min<size_t>(n, cont->size()));
   return std::shared_ptr<typename T>(new T(cont->end() - size, cont->end()));
}

Produces the following error on gcc 4.7.2.

g++ test.cpp -std=c++0x
test.cpp:4:27: error: template argument 1 is invalid
test.cpp:4:66: error: template argument 1 is invalid
test.cpp: In function ‘int Tail(const int&, size_t)’:
test.cpp:6:42: error: base operand of ‘->’ is not a pointer
test.cpp:7:35: error: template argument 1 is invalid
test.cpp:7:47: error: base operand of ‘->’ is not a pointer
test.cpp:7:67: error: base operand of ‘->’ is not a pointer

I understand that cont does not 'look' like a pointer, but this compiles fine on VS2012. How can I write the function for gcc?

Craig
  • 413
  • 7
  • 16

3 Answers3

3

Just remove those extra typenames

template<typename T>
std::shared_ptr<T> Tail(const std::shared_ptr< T>& cont, size_t n)
{
   const auto size(std::min<size_t>(n, cont->size()));
   return std::shared_ptr< T>(new T(cont->end() - size, cont->end()));
}
masoud
  • 55,379
  • 16
  • 141
  • 208
2

You are overusing the typename keyword. The code should look as follows:

template<typename T>
std::shared_ptr<T> Tail(const std::shared_ptr<T>& cont, size_t n)
{
   const auto size(std::min<size_t>(n, cont->size()));
   return std::shared_ptr<T>(new T(cont->end() - size, cont->end()));
}

For further discussion, see Where and why do I have to put the "template" and "typename" keywords?

Community
  • 1
  • 1
NPE
  • 486,780
  • 108
  • 951
  • 1,012
0

you don't have to rewrite typename before every use of arguments, so please change it to:

template<typename T>
std::shared_ptr<typename T> Tail(const std::shared_ptr<T>& cont, size_t n)
{
   const auto size(std::min<size_t>(n, cont->size()));
   return std::shared_ptr<typename T>(new T(cont->end() - size, cont->end()));
}

this is the same issue as with i.e. classes, you don't write void myfunc(class MyClass &m){} but simply void myfunc(MyClass &m){}

4pie0
  • 29,204
  • 9
  • 82
  • 118