Jaebum
Jaebum

Reputation: 1570

ostream friend function of specialized template class

template <> 
class test<int> {
    int y; 
public:     
    test(int k) : y(k) {}     
    friend ofstream& operator<< <test<int>> (ofstream& os, const test<int>& t); 
};  
template<> 
ofstream& operator<< <test<int> > (ofstream& os, const test<int>& t) 
{
    os << t.y;
    return os;
}  

The code above is specialized template class of test in a int version. I am trying to overload ofstream operator<< function. But it shows error message;

C2027: use of undefined type 'std::basic_ofstream<_Elem,_Traits>'

Besides, the same method works on a ordinary function (not ofstream operator<< but the function that I make) Is there anyway to us operator<< function of ofstream in a specialized template class ?

Upvotes: 1

Views: 2341

Answers (2)

Aaron McDaid
Aaron McDaid

Reputation: 27163

There are a number of interesting issues here. First the obvious housekeeping

  • You should #include <fstream> and don't forget using namespace std.
  • operator << shouldn't be a template, it should be an overloaded function.
  • os << t.y confuses the compiler for me (g++ 4.4.3: "warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:"). You intend to push the int to the stream obviously, but the compiler notices that an int can be turned into a test<int> via your constructor and therefore it doesn't know whether you want to push an int or a test<int>. This is stupid I know, and can be solved by making the constructor explicit.

    #include <fstream>
    using namespace std;
    template <typename T>
    class test;
    
    template <>
    class test<int> {
        int y;
    public:
        explicit test(int k) : y(k) {}
        // friend ofstream& operator<<   < test<int> > (ofstream& os, const test<int>& t); 
        friend ofstream& operator<< (ofstream& os, const test<int>& t);
    };
    // template<> 
    // ofstream& operator<< <test<int> > (ofstream& os, const test<int>& t) 
    ofstream& operator<<  (ofstream& os, const test<int>& t)
    {
        os << t.y;
        return os;
    }
    int main() {
    }
    

Upvotes: 0

sehe
sehe

Reputation: 393613

You need to include

 #include <iostream>

At the time of instantiation of the function template. Perhaps you only included

 #include <iosfwd>

Besides, you shouldn't be defining (static) friend as a template: https://ideone.com/1HRlZ

#include <iostream>

template <typename> class test;

template <> 
class test<int> {
    int y; 
public:     
    test(int k) : y(k) {}     
    friend std::ostream& operator<<(std::ostream& os, const test& t); 
};  

std::ostream& operator<< (std::ostream& os, const test<int>& t) 
{
    return os << t.y;
}  

int main()
{
    test<int> a(42);
    std::cout << a << std::endl;
}

Note that it isn't a good idea to have 'using namespace std' in your header file, which is why I removed it from the sample. (It might cause conflicts for users of your header file when they include your header)

Upvotes: 1

Related Questions