tags:

views:

62

answers:

1

I have a structure with a template parameter, Stream. Within that structure, there is a function with its own template parameter, Type.

If I try to force a specific instance of the function to be generated and called, it works fine, if I am in a context where the exact type of the structure is known. If not, I get a compile error. This feels like a situation where I'm missing a typename, but there are no nested types. I suspect I'm missing something fundamental, but I've been staring at this code for so long all I see are redheads, and frankly writing code that uses templates has never been my forte.

The following is the simplest example I could come up with that illustrates the issue.

#include <iostream>

template<typename Stream>
struct Printer {
  Stream& str;
  Printer(Stream& str_) : str(str_) { }

  template<typename Type>
  Stream& Exec(const Type& t) {
    return str << t << std::endl;
  }
};

template<typename Stream, typename Type>
void Test1(Stream& str, const Type& t) {
  Printer<Stream> out = Printer<Stream>(str);
  /****** vvv This is the line the compiler doesn't like vvv ******/
  out.Exec<bool>(t); 
  /****** ^^^ That is the line the compiler doesn't like ^^^ ******/
}

template<typename Type>
void Test2(const Type& t) {
  Printer<std::ostream> out = Printer<std::ostream>(std::cout);
  out.Exec<bool>(t);
}

template<typename Stream, typename Type>
void Test3(Stream& str, const Type& t) {
    Printer<Stream> out = Printer<Stream>(str);
    out.Exec(t);
}

int main() {
  Test2(5);
  Test3(std::cout, 5);
  return 0;
}

As it is written, gcc-4.4 gives the following:

test.cpp: In function 'void Test1(Stream&, const Type&)':
test.cpp:22: error: expected primary-expression before 'bool'
test.cpp:22: error: expected ';' before 'bool'

Test2 and Test3 both compile cleanly, and if I comment out Test1 the program executes, and I get "1 5" as I expect. So it looks like there's nothing wrong with the idea of what I want to do, but I've botched something in the implementation.

If anybody could shed some light on what I'm overlooking, it would be greatly appreciated.

+4  A: 

You need to tell the compiler that the dependent name Printer<Stream>::Exec is a template:

out.template Exec<bool>(t);

It's the same principle as with typename, just that in this case the problematic name is not a type, but a template.

sth
Thank you so very much. I can't recall ever coming across that syntax before.
Dennis Zickefoose