List::Node* lastNode(Node* root) { ... }
определяет глобальную функцию с именем lastNode
, возвращающую List::Node*
. Вы хотели определить это как член функция List
. Чтобы сделать это, вы просто квалифицируете имя lastNode
как List::
.
List::Node *List::lastNode(Node *root) { ... } // * placement is more idiomatic this way
Второй List::
в имени функции объявляет, что эта функция "принадлежит" к List
, поэтому второй Node
, следующий за ним, не нуждается в повторном уточнении List::
. Тип возвращаемого значения, поскольку он предшествует List::
на последнем узле, все еще интерпретируется в глобальной области видимости, и поэтому его необходимо квалифицировать. Я не думаю, что для этого есть какая-либо веская причина, кроме исторической инерции, пережитка того времени, когда компиляторы были настолько глупы, чтобы запутаться в этом. Вы также можете поместить тип возврата после квалифицированного имени функции, где вы можете опустить квалификатор:
auto List::lastNode(Node *root) -> Node* { ... }
Godbolt