tl; dr
Учитывая определение foo ниже, почему вызовКод: Выделить всё
Foo{2}();
OK, по-видимому, очень похожий пример показан в шаблонах c ++-Полное руководство в §14.3.2, и причина примерно то, что при сначала видно любое неквалифицированное инициатив (например, код, который (), который
// the cpp files
void draw(int) {
std::cout
g++ -std=c++20 *.cpp -O0 -o main && ./main
< /code>
успешно и печатает < /p>
Bar
int
[/code]
Вызов void bar :: draw (bar :: bar) возможен из-за ADL, и нам даже не нужна bar :: bar и bar :: draw будет объявлена каким-либо образом, прежде чем foo для работы, т.е.
Код: Выделить всё
#include "bar.hpp"
#include "foo.hpp"
< /code>
to < /p>
#include "foo.hpp"
#include "bar.hpp"
< /code>
не влияет на программу (я получаю такой же двоичный файл). В конце концов, внутренняя часть оператора ()
Код: Выделить всё
Foo{bar::Bar{}}();
С другой стороны, вызов void draw (int) , который соответствует
Код: Выделить всё
Foo{2}();
But why does that imply that the declaration of that overload of draw must be visible before the definition of Foo, which in turns means that the order of #includes in main becomes important?
Я имею в виду, к тому времени < /p>
Код: Выделить всё
Foo{2}();
И, какой бы ни была причина, является ли это симптом плохого дизайна? В этом отношении я думаю о концепции времени выполнения Sean Runtime Idiom (звонок ADL - 35:57 лучшего кода: полиморфизм времени выполнения - Sean Parent).
Подробнее здесь: https://stackoverflow.com/questions/786 ... isible-bef