一个模板类友元函数的内部类

4

我有一个模板类A,其中包含内部类B。我想要一个友元等于运算符。
然而,以下代码无法编译通过,它会显示:couldn't deduce template parameter ‘T’

#include <iostream>

template<typename T>
struct A
{
    struct B
    {
        T b;

        template<typename T2>
        friend bool operator == (const typename A<T2>::B& b1, const typename A<T2>::B& b2);
    };

    B b;
};

template<typename T>
bool operator == (const typename A<T>::B& b1, const typename A<T>::B& b2)
{
    return b1.b == b2.b;
}

int main() {
    A<int>::B b1, b2;
    b1.b = 3;
    b2.b = 2;

    std::cout << (b1 == b2) << std::endl;

    return 0;
}

我必须使用友元版本,因为 STL 算法的调用方式会导致无法找到 ==,即使我有bool operator == (const B& b_) { return b == b_.b; }

如何解决这个问题?


3
我猜这个问题是由于你在成员函数 operator== 中忘记加上 const 修饰符所导致的。这里有对你问题的解释。 - LogicStuff
@LogicStuff 在哪里添加 const?它说这是一个非成员函数。我不太明白。 - Mochan
@JeJo 我必须使用友元版本。它在这个例子中可以工作,但在我的实际代码库中无法工作。 - Mochan
1
@Mochan,你在bool operator ==中使用了赋值符号(=)而不是相等符号(==)。 - aparpara
@aparpara 抱歉打错了,我把那个当作注释写进去了,实际上并不是代码。 - Mochan
@JeJo 您的答案是解决方案。 - Mochan
2个回答

4

这是一个非推导上下文

表面上,你可以有这样的定义:

template<typename AB>
bool operator == (const AB& b1, const AB& b2)
{
    return b1.b == b2.b;
}

但是它范围太广了,因为它包含了所有类型。你可以通过以下方式限制它。

template<typename AB>
auto operator == (const AB& b1, const AB& b2) ->
     std::enable_if_t<std::is_same_v<AB, typename A<decltype(b1.b)>::B>, bool>
{
    return b1.b == b2.b;
}

1
这是一个非常好的解决方案。运行得很好。我以前从未听说过非推断上下文。谢谢。 - Mochan

1

这对我起作用了。

#include <iostream>

template<typename T>
struct A
{
    struct B
    {
        T b;
    };

    friend bool operator==(const typename A<T>::B &b1, const typename A<T>::B &b2)
    {
        return b1.b == b2.b;
    }

    B b;
};

int main() {
    A<int>::B b1, b2;
    b1.b = 3;
    b2.b = 2;

    std::cout << (b1 == b2) << std::endl;

    return 0;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接