M
Maxim Yegorushkin
I have a template class and a friend template function definition in the definition of the class. The problem is that the function's declaration has access to the class's template parameters but the function's body (definition) does not.
I believe that the function's body must have the access according to the standard [11.4.5]: A friend function defined in a class is in the (lexical) scope of the class in which it is defined. A friend function defined outside the class is not (3.4.1).
VC7.1 conforms to the standard when a friend function is not templated and does not conform otherwise.
The following code snippet, perfectly compilable with Comeau online, Intel C++ Compiler 8.0, gcc 3.2, produces an error when compiled with MS VC7.1.
Does anybody have explanation for VC's behavior?
#include <iostream>
#include <ctime>
namespace util
{
template<class derived_t>
struct io_manipulator_concept
{
template<class T, class U>
friend std::basic_ostream<T, U>& operator<<(
std::basic_ostream<T, U>& stream
, io_manipulator_concept<derived_t> const& manip
)
{
static_cast<derived_t const&>(manip).out(stream); // error C2061: syntax error : identifier 'derived_t'
return stream;
}
};
} // namespace util {
struct time_manipulator_model : util::io_manipulator_concept<time_manipulator_model>
{
void out(std:stream& stream) const
{
time_t t;
std::time(&t);
stream << std::ctime(&t);
}
} time_manip;
int main()
{
std::cout << time_manip << '\n';
}
I believe that the function's body must have the access according to the standard [11.4.5]: A friend function defined in a class is in the (lexical) scope of the class in which it is defined. A friend function defined outside the class is not (3.4.1).
VC7.1 conforms to the standard when a friend function is not templated and does not conform otherwise.
The following code snippet, perfectly compilable with Comeau online, Intel C++ Compiler 8.0, gcc 3.2, produces an error when compiled with MS VC7.1.
Does anybody have explanation for VC's behavior?
#include <iostream>
#include <ctime>
namespace util
{
template<class derived_t>
struct io_manipulator_concept
{
template<class T, class U>
friend std::basic_ostream<T, U>& operator<<(
std::basic_ostream<T, U>& stream
, io_manipulator_concept<derived_t> const& manip
)
{
static_cast<derived_t const&>(manip).out(stream); // error C2061: syntax error : identifier 'derived_t'
return stream;
}
};
} // namespace util {
struct time_manipulator_model : util::io_manipulator_concept<time_manipulator_model>
{
void out(std:stream& stream) const
{
time_t t;
std::time(&t);
stream << std::ctime(&t);
}
} time_manip;
int main()
{
std::cout << time_manip << '\n';
}