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.