How to split function definition of template name in template class?

The following example compiles fine, but I cannot figure out how to separate the declaration and definition of the <<() operator in this particular case.

Every time I try to share a different definition, a problem occurs and gcc complains that the <<() operator should only take one argument.

#include <iostream>
template <typename T>
class Test {
    public:
        Test(const T& value) : value_(value) {}

        template <typename STREAM>
        friend STREAM& operator<<(STREAM& os, const Test<T>& rhs) {
            os << rhs.value_;
            return os;
        }
    private:
        T value_;
};

int main() {
    std::cout << Test<int>(5) << std::endl;
}

The operator <(lt) must have a free first parameter for working with various types of output streams (std :: cout, std :: wcout or boost :: asio :: ip :: tcp :: iostream). The second parameter must be bound to a specialized versions of the surrounding class.

Test<int> x;
some_other_class y;

std::cout << x; // works
boost::asio::ip::tcp::iostream << x; // works

std::cout << y; // doesn't work
boost::asio::ip::tcp::iostream << y; // works

, , , , , , .

+3
5

, , :

#include <iostream>
template <typename T>
class Test
{
    public:
        Test(const T& value) : value_(value) {}

        template <typename STREAM, typename U>
        friend STREAM& operator<<(STREAM& os, const Test<U>& rhs);

    private:
        T value_;
};

template <typename STREAM, typename T>
STREAM& operator<<( STREAM& os, const Test<T>& rhs )
{
    os << rhs.value_;
    return os;
}
+4

?

template <typename T>
class Test 
{  
    ...
    template <typename STREAM>
    friend STREAM& operator<<(STREAM& os, const Test<T>& rhs);
};

template <typename STREAM, typename T> 
STREAM& operator<<(STREAM& os, const Test<T>& rhs) 
{
    os << rhs.value_;
    return os;
}
+1

, ,

#include <iostream>

template <typename T>
class Test;

template <typename STREAM, typename T>
STREAM& operator<<(STREAM& os, const Test<T>& rhs);

template <typename T>
class Test {
public:
    Test(const T& value) : value_(value) {}

    template <typename STREAM, typename U>
    friend STREAM& operator<< (STREAM& os, const Test<U>& rhs);

private:
    T value_;
};

template <typename STREAM, typename T>
STREAM& operator<<(STREAM& os, const Test<T>& rhs) {
    os << rhs.value_;
    return os;
}

int main() {
    std::cout << Test<int>(5) << std::endl;
}

< , , . , .

template <typename STREAM>
friend STREAM& operator<< <STREAM, T> (STREAM& os, const Test<T>& rhs);

. ( )

+1

, , , , . T ( mytype) :

template <typename STREAM>
STREAM& operator<<( STREAM& os, Test<mytype> const & x );

, Test<mytype> Test mytype.

, , Test, .

, operator<< , ( ).

0

T Test <(), . <() , .

:

Test<int> x;
some_other_class y;

std::cout << x; // works
boost::asio::ip::tcp::iostream << x; // works

std::cout << y; // doesn't work
boost::asio::ip::tcp::iostream << y; // works

, Test.

0

Source: https://habr.com/ru/post/1745125/


All Articles