Reputation: 4191
The example below is a distilled version of a problem with templates I'm having - please see compilation errors below.
#include <iostream>
#include <vector>
template <class T> struct S
{
typedef std::vector<T> SVec;
};
template <class T> std::ostream& operator<<(std::ostream& OS, const S<T>::SVec& X)
{
for (const auto& e: X) OS << e << ' ';
return OS;
}
int main()
{
S<int>::SVec v;
std::cout << v << std::endl;
}
Compiler output:
g++ -g -Wall -O4 -std=c++11 -c tc041.cpp
tc041.cpp:22:69: error: need ‘typename’ before ‘S<T>::SVec’ because ‘S<T>’ is a dependent scope
template <class T> std::ostream& operator<<(std::ostream& OS, const S<T>::SVec& X)
And so on - hundreds of lines. My compiler - g++ 5.2.1, OS - Xubuntu 4.2.0.
How to make this operator to be compiled correctly?
Upvotes: 3
Views: 386
Reputation:
There are two problems:
typename
keyword at the operator declaration.main
.template <class T>
std::ostream& operator<<(std::ostream& OS, const typename S<T>::SVec& X)
A typename
keyword should be placed before S<T>::SVec
. Due to language rules, the compiler does not know whether SVec
is a member type or something else. The typename
keyword is to tell the compiler it is a type.
For details of the language rules, you may refer to: http://en.cppreference.com/w/cpp/language/dependent_name
(Note: I am actually less sure about it because this scenario is new to me too.)
Let's do an experiment. Instead of invoking operator<<
with operator syntax, let's invoke it with function syntax.
operator<< (std::cout, v);
Well, it still fails.
What if we invoke it with explicit template argument?
operator<< <int> (std::cout, v);
It works! Well, actually, may work. I find that some standard library header may contain something that interferes it. But let's put it aside.
The problem this experiment demonstrates is that the template argument deduction fails. Argument type of the form class-template-name<T>::member-type
cannot be deduced.
Details: http://en.cppreference.com/w/cpp/language/template_argument_deduction
Upvotes: 3