如何正确定义好友免费功能

How to properly define friend free functions

背景

我正在尝试编写一个包含迭代器的容器。例如。它创建间接范围。我希望范围的迭代器取消引用底层迭代器。我这样做了,但是我需要关系运算符。这是重现问题的简化版本:

mcve

template <typename T>
struct foo
{
    class bar
    {
        friend bool do_something(bar);
    };

    bar get_bar()
    {
        return bar{};
    }
};

template <typename T>
bool do_something(typename foo<T>::bar)
{
    return true;
}

#include <iostream>

int main()
{
    foo<int> f;
    auto b = f.get_bar();
    std::cout << do_something(b);
}

/tmp/prog-c08a3a.o: In function main': prog.cc:(.text+0x12): undefined reference todo_something(foo::bar)'

demo on wandbox.

这是我遇到的唯一错误。

问题

什么在 class 内部声明,什么在 class 外部定义为自由函数?

我试过的

编译器让我放一个模板,但这显然不是我想要的。我不希望与一种 ForwardIterator 类型相关的迭代器与另一种 ForwardIterator 类型的迭代器具有可比性。但我想好吧,让我们试试看,但它给了我阴影错误,这更加加深了我的怀疑。

为什么要在里面定义

据我所知,在内部定义它将使它只能调用 ADL。有些 IDE 可能无法理解这一点,所以我认为在外部声明它们会更好。

更简单的方法是直接在 class:

中定义函数
template <typename T>
struct foo
{
    class bar
    {
        friend bool do_something(bar) { /* implementation */}
    };

    bar get_bar()
    {
        return bar{};
    }
};