1

In the following code, lets say I want to call a specific function template instantiation based on a runtime value. I am going to need to do this a bunch of times for different functions, so I wanted to wrap the conditionals in a function (test) and pass the function template "func". So I wrap the "func" template in a struct…like so:

#include<iostream>
#include<typeinfo>


struct wrapper
{
public:
  template< typename T >
  static int funcT( int a )
  {
    std::cout<<"your func type and value is "<<typeid(T).name()<<" "<<a<<std::endl;
  }

  static int func( int a )
  {
    std::cout<<"your func type and value is "<<typeid(int).name()<<" "<<a<<std::endl;
  }

};

enum class TypeIDs
{
  real8_id,
  int4_id
};


template< typename WRAPPER, typename RTYPE, typename...ArgsF >
static RTYPE test( const TypeIDs type, ArgsF... args )
{

  RTYPE junk = WRAPPER::func(args... );

  RTYPE rval;
  switch( type )
  {
    case( TypeIDs::real8_id ):
    {
      rval = typename WRAPPER::funcT<double>(args...);
      break;
    }
    case( TypeIDs::int4_id ):
    {
      rval = WRAPPER::funcT<int>(args... );
      break;
    }
  }


  return rval;
}

int main()
{
  wrapper::funcT<double>(1);
  test<wrapper,int>(TypeIDs::real8_id, 1);
}

compilation results in:

g++48 -std=c++11 templatesandfunctions.cpp 
templatesandfunctions.cpp: In function 'RTYPE test(TypeIDs, ArgsF ...)':
templatesandfunctions.cpp:47:37: error: expected '(' before '<' token
       rval = typename WRAPPER::funcT<double>(args...);
                                     ^
templatesandfunctions.cpp:47:38: error: expected primary-expression before 'double'
       rval = typename WRAPPER::funcT<double>(args...);
                                      ^
templatesandfunctions.cpp:47:38: error: expected ';' before 'double'
templatesandfunctions.cpp:52:29: error: expected primary-expression before 'int'
       rval = WRAPPER::funcT<int>(args... );
                             ^
templatesandfunctions.cpp:52:29: error: expected ';' before 'int'

So:

wrapper::funcT<double>(1)

called from main compiles…as expected.

From the call

test<wrapper,int>(TypeIDs::real8_id, 1);"

The non-templated function

WRAPPER::func(args... );

does compile.

However the templated function does not compile with and without the typename specifier.

WRAPPER::funcT<double>(args…);
typename WRAPPER::funcT<double>(args…);

Anyone know why this doesn't work…and how to make it work?

Thanks!

doc07b5
  • 600
  • 1
  • 7
  • 18

1 Answers1

3

Use template to inform the compiler it's dealing with a dependent template name (and omit the typename):

rval = WRAPPER::template funcT<double>(args...);
                ^^^^^^^^

Without the disambiguation, the compiler will interpret < as less than.

justin
  • 104,054
  • 14
  • 179
  • 226
  • well that works! Thanks a lot. I have never even seen that requirement! One question if you don't mind…why does the template call in main work then? It seems like that one shouldn't work if the compiler was going to be strict about it. – doc07b5 Nov 26 '14 at 07:32
  • @doc07b5 updated. the compiler is just shy of being able to parse it. See: http://en.cppreference.com/w/cpp/language/dependent_name Section: "The template disambiguator for dependent names" – justin Nov 26 '14 at 07:46