Background
I'm trying to write a container which will contain iterators. E.g. it creates indirection range. I want the iterator of the range to dereference underlying iterator. I did that, but then I need relational operators. Here is the reduced version that reproduces the problem:
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 to
do_something(foo::bar)'
This is the only error I get.
Question
What is declared inside of the class and what is defined as free function outside of the class?
What I tried
Compiler asks me to put a template, but that is clearly not what I want. I don't want my iterator related to one ForwardIterator
type to be comparable to iterator of another ForwardIterator
type. But I thought ok, lets try that, but it gave me shadowing error, which strengthened my suspicions.
Reasons why I want to define inside
From what I've heard, defining it inside will make it only ADL callable. Some IDEs might not figure that out, so I thought that declaring them outside is better.