c++ 在模板结构中重载结构的运算符[重复]

7kjnsjlb  于 11个月前  发布在  其他
关注(0)|答案(2)|浏览(80)

此问题在此处已有答案

friend operator in nested class of templated class(1个答案)
4天前关闭。
我有一个模板结构Foo,它定义了一个内部结构Bar
现在,我想为这个内部结构Bar重载流operator <<,但是编译器似乎忽略了我的重载实现:
错误:没有匹配'operator<<'(操作数类型是'std::ostream' {aka 'std::basic_ostream '}和'Foo::Bar'<3>)
代码如下:

#include <iostream>

//////////////////////////////////////////////////////////////////////////////////////////
template<int N>
struct Foo
{
    struct Bar  {};
};

//////////////////////////////////////////////////////////////////////////////////////////
template<int N>
std::ostream& operator<< (std::ostream& os, const typename Foo<N>::Bar& x)
{
    return os;
}

//////////////////////////////////////////////////////////////////////////////////////////
int main (int argc, char** argv)
{
    Foo<3>::Bar x;

    std::cout << x << std::endl;
}

字符串
我看不出(可能是明显的)错误。

问题是否可以重载属于模板类的内部结构的操作符?

zi8p0yeb

zi8p0yeb1#

是的,就像这样:

#include <iostream>

template<int N>
struct Foo
{
    struct Bar  {
        friend std::ostream& operator<<(std::ostream& os,const Bar&) { return os;}
    };
};

int main (int argc, char** argv)
{
    Foo<3>::Bar x;

    std::cout << x << std::endl;
}

字符串
在你的代码中,operator<<实际上并没有错。它只是不可能从Foo<N>::Bar推导出N。你只能通过显式地调用N

int main (int argc, char** argv)
{
    Foo<3>::Bar x;
    operator<<<3>(std::cout,x);
}


Live Demo的一个。
原因是Foo<N>::Bar是一个非推导上下文。有关更多详细信息,请参阅What is a non-deduced context?。简单地说,这不起作用的原因是Foo<N>::BarN之间没有1:1的关系。请考虑添加一个专用化:

template <> struct Foo<42> {
      using Bar = Foo<3>::Bar;
};


现在,Foo<42>::BarFoo<3>::Bar引用的是完全相同的类型。

Foo<3>::Bar x;
std::cout << x;


而这

Foo<42>::Bar x;
std::cout << x;


必须推导出N的不同值,但是在两个示例中x是完全相同的类型。

nr9pn0ug

nr9pn0ug2#

你的意思是这样的吗?使用模板类,通常在模板中声明友元重载会更容易(示例在这里:https://onlinegdb.com/NqTLD6_tU

#include <iostream>

template<int N>
struct Foo
{
    struct Bar
    { 
        int x{N};
    };
    
    // friend if you need access to a private member
    friend std::ostream& operator<<(std::ostream& os, const Foo<N>::Bar& bar)
    {
        os << bar.x;
        return os;
    }

private:
    Bar b; 
};

int main (int argc, char** argv)
{
    Foo<3>::Bar x;
    std::cout << x << "\n";
}

字符串

相关问题