0

The following program, if compiled as shown, outputs size: 1 align: 1.

However, trying to make the same method-template call from a templatized function doesn't work.

If I change #if 0 to #if 1 g++ 9.2.1 gives me error expected primary-expression before 'char'. clang++ gives a more helpful-sounding error: use 'template' keyword to treat 'log' as a dependent template name but I'm not sure where it wants template to occur.

So what gives?

#include <iostream>
using namespace std;



class Foo {

public:
  Foo() {};
  ~Foo() {};
  void log( int iSizeItem, int iAlignItem ) {
    cout << "size: " << iSizeItem << "  align: " << iAlignItem << endl;
  }
  
  template<class T> void log() {
    log( sizeof( T ), alignof( T ) );
  }
};


#if 0
template<class T> void Test( T& t ) {
  t.log<char>();
}
#endif


int main( int nArg, char* apszArg[] ) {
  Foo foo;
  foo.log<char>();

  //Test( foo );

  return 0;
}
cigien
  • 57,834
  • 11
  • 73
  • 112
Swiss Frank
  • 1,985
  • 15
  • 33
  • My question is apparently also answered under a omnibus question of: https://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-the-template-and-typename-keywords ... however I find that question overly broad. If anything it should be broken into pieces, like mine, that are easier to find. – Swiss Frank Jun 29 '20 at 07:04

1 Answers1

1

You need to specify that log is a function template, like this:

template<class T> void Test( T& t ) {
  t.template log<char>();
}

Otherwise the compiler doesn't know if log is a member of T, and < is actually operator<.

Here's a demo.

cigien
  • 57,834
  • 11
  • 73
  • 112
  • Works perfectly in g++ 9.2.1 and clang++ 9.0.1. No idea why you got down-voted for it! I've programmed C++ since 1992 and not seen that syntax before... – Swiss Frank Jun 29 '20 at 07:02