Jump to content


c++ call templated function on template parameter


  • You cannot reply to this topic
3 replies to this topic

#1 ElOmmy

    New Member

  • Members
  • Pip
  • 7 posts

Posted 31 October 2006 - 09:38 PM

Hey,
i have a litte problem concerning nested templated types/functions in a class used as a template param, and would like to hear your inputs/ideas/workarounds...

basically, i tried to do this (well, simplified example):

struct holder1

{

  template <int i>

  static void func()

  {

    cout << i << endl;

  }

};

template <typename T>

struct holder2

{

  static void func()

  {

    T::func<5>();

  };

};


this works with VC++ 2005, but doesnt work with the latest GCC (or any GCC). since VC++ has a history of parsing non-standard c++, is this code standards-conforming? if not, what should i change? if yes, what should i change to get this compiled with gcc?

i also tried another possibility:


struct holder1

{

  template <int i>

  struct nested

  {

    static void func()

    {

      cout << i << endl;

    }

  };

};

template <typename T>

struct holder2

{

  static void func()

  {

    T::nested<5>::func(); // ok, this shouldn't really work

    // but this one should:

    typedef typename T::nested<5> nested_t;

    nested_t::func();

  };

};


doesn't work either... any ideas on how to fix this?

thanks in advance
ElOmmy

#2 .oisyn

    DevMaster Staff

  • Moderators
  • 1822 posts

Posted 31 October 2006 - 10:50 PM

The problem is indeed that it isn't correctly formalized standard C++. T is a template parameter, so T::func is a dependent name. Now this case leads to a parse error, but what about this:

template <typename T>
struct holder2
{
  static void func()
  {
    T::func<5>(3);
  };
};

Do you mean to call a template function, or do you want to test whether func is smaller than 5 and the result of that is larger than 3? The point is that the actual definition of func is not known when parsing the template class holder2, so you have to give the compiler some hints about how to interpret your code.

You probably already know the typename keyword, to indicate that a dependent name is a type. In this case you have to use the template keyword to define that the name is in fact a template, so the <5> will parsed as template arguments to func.

T::template func<5>();

C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#3 bladder

    DevMaster Staff

  • Moderators
  • 1057 posts

Posted 01 November 2006 - 07:51 AM

.oysin cleared that up very well, just wanted to add that the template keyword is required when you are accessing a member template from a dependant name. Not only when using the :: operator, but also the . and the -> operators, eg:

template< class T >
void f( T a, T* p ) {
    a.template func<3>();
    p->template func<3>();
}

exact words of the standard are:

"When the name of a member template specialization appears after . or -> in a postfix-expression, or after a nested-namespecifier in a qualified-id, and the postfix-expression or qualified-id explicitly depends on a template-parameter (14.6.2) but does not refer to a member of the current instantiation (14.6.2.1), the member template name must be prefixed by the keyword template. Otherwise the name is assumed to name a non-template." [section 14.2.4]

#4 ElOmmy

    New Member

  • Members
  • Pip
  • 7 posts

Posted 01 November 2006 - 08:35 PM

wow thx, this really helped (and compiles seamlessly). as it appears, one can never know everything about c++ (or, at least, i can't ;) )





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users