当前位置: 首页 > 知识库问答 >
问题:

模板类的friend运算符

毛胜
2023-03-14

在下面的代码中,是一个模板类,取决于非类型bool type参数。为A A 定义了friend运算符<<运算符<<还依赖于另一个bool模板参数。

#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;
}

在Coliru上看现场直播。

现在,我想给出运算符<<的模板参数d的默认值,例如d=false,以便以下语句

std::cout << atrue;

相当于

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

如果我在运算符的代码中插入默认参数<<

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

同样,它不编译给出错误

main.cpp:27:15:错误:重新声明friend'template std::ostream&operator<<(std::ostream&,const a&)'可能没有默认模板参数

main.cpp:14:26:注意:“template std::ostream&operator<<(std::ostream&,const a&)”以前在这里声明过

14 friend STD::oStream&Operator<(STD::oStream&os,const a&a);

共有1个答案

桓宜
2023-03-14

好的,实际上解决方案是相对容易的。在类专门化之前添加模板运算符<<的声明就足够了:

template <bool type>
class A;

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

这样,a 中的friend声明并不首先声明运算符<<,而只声明它是friend。可以在这里查看一个工作示例。

 类似资料:
  • 我在运算符过载时遇到问题 主要是我有 其中<code>Integer</code>只是<code>int</code>的包装,带有我需要的一些特殊功能。 然而,当我编译上面的代码时,我得到了错误C2679,它表示<code>binary' 我还试图删除友元声明中的参数,因此代码变成了: 但这会产生另一个错误:C2785:

  • 我有一个模板类包含其他类的优先级队列,我需要使用优先级重载器调用各个类重载器,根据各个类的偏好进行比较(在这种情况下是年龄,在另一个类中可能是价格。 我绝对相信我已经实现了不正确的运算符重载,因此非常感谢您的建议。 举个例子 我得到这个错误,我不知道我需要做什么来修复它。我必须将类重载保持为单个变量(Animal) 任务cpp:在“布尔运算符”的实例化中

  • 我在surf.h中有以下代码,其中声明了一个具有两种不同类型的模板类: 然后定义一个新类,其中创建了一个类型为T的向量(在field.h中) 在main.cpp中,我使用了这个字段。 我用G++(版本5.4)编译它,得到以下错误: 从main.cpp:2:0:field.h:在“std::ostream&operator<<(std::ostream&,const field&)[with T=s

  • 我有一个全局函数是这样的: 然后在另一个类中,我要将这个函数声明为的朋友。所以我做了: 现在,当我调用时,它无法编译,错误是foo无法访问的私有构造函数。我无法理解该错误,如何正确声明为的朋友? 提前道谢。

  • 这在gcc中编译,但在clang和最新的MSVC预览编译器中都不编译 下一个尝试是使用friend声明中的约束,即。 这看起来像是一种自然的方式,因为无论如何只能在满足约束的情况下实例化friend。

  • 因此,我试图在模板类中包含输入和输出运算符的两个友元声明,但每次编译代码时,它似乎都无法识别该运算符。这是我的头文件。 错误:严重性代码描述项目文件行抑制状态错误LNK2019未解析外部符号“class std::basic_ostream” 这似乎是一个链接错误。 屏幕h 这是我的主要cpp文件 main.cpp 我注意到这个问题可以通过在类体中包含友元声明和函数定义来解决,但是我不想这样做。