模板类的好友运算符<

问题描述 投票:0回答:1

在下面的代码中,A是模板类,取决于非类型的bool type参数。为operator<<A<true>都定义了一个朋友A<false>operator<<另外取决于另一个布尔模板参数。

#include <ostream>
#include <iostream>
#include <type_traits>

template <bool type>
class A;

template <>
class A<true> {
    int m_x;
public:
    A(int x) : m_x{x} { }
    template <bool d, bool type>
    friend std::ostream& operator<<(std::ostream& os, const A<type>& a);
};

template <>
class A<false> {
    int m_y;
public:
    A(int y) : m_y{y} { }
    template <bool d, bool type>
    friend std::ostream& operator<<(std::ostream& os, const A<type>& a);
};

template <bool d, bool type>
std::ostream& operator<<(std::ostream& os, const A<type>& a)
{
    if constexpr (type) {
        os << "m_x = " << a.m_x << std::endl;
        if constexpr (d) { os << "2m_x = " << a.m_x << std::endl; }
    }
    else {
        os << "m_y = " << a.m_y << std::endl;
        if constexpr (d) { os << "2m_y = " << a.m_y << std::endl; }
    }
    return os;
}


int main()
{
    A<true> atrue{2};
    A<false> afalse{3};

    operator<< <true>(std::cout, atrue);
    operator<< <false>(std::cout, atrue);

    operator<< <true>(std::cout, afalse);
    operator<< <false>(std::cout, afalse);

    return 0;
}

查看live on Coliru

现在,我想提供模板参数d的默认值operator<<,例如说d=false这样的语句

std::cout << atrue;

相当于

operator<< <false>(std::cout, atrue);

因为bool d采用默认值d=false,并且从bool type的第二个参数推导出operator<<

是否有允许使用的语法?

如果我在朋友声明中插入默认参数

template <bool d = false, bool type>
friend std::ostream& operator<<(std::ostream& os, const A<type>& a);

我收到编译错误:

main.cpp:14:71:错误:默认模板参数可能不用于模板朋友声明

如果我在operator<<的代码中插入默认参数,则>

template <bool d = false, bool type>
std::ostream& operator<<(std::ostream& os, const A<type>& a)
{
...

同样不会编译并给出错误

main.cpp:27:15:错误:朋友'模板std :: ostream&运算符<

27 | std :: ostream&运算符<

main.cpp:14:26:注意:'template std :: ostream&运算符<

14 |朋友std :: ostream&运算符<

在以下代码中,A是模板类,取决于非类型布尔类型参数。为A 和A 都定义了一个朋友运算符<] >>

好,实际上解决方案相对容易。在类专业化之前添加模板operator<<declaration

就足够了:
template <bool type>
class A;

template <bool d = false, bool type>
std::ostream& operator<<(std::ostream& os, const A<type>& a);
....

以这种方式,friend中的A<type>声明不会首先声明operator<<,而只会声明它是friend。可以检查一个有效的例子here

c++ templates operator-overloading friend
1个回答
0
投票

好,实际上解决方案相对容易。在类专业化之前添加模板operator<<declaration

就足够了:
© www.soinside.com 2019 - 2024. All rights reserved.