Error: "Friend-Member Function Name" was not declared in this scope

I run all my C ++ Windows applications on Ubuntu Linux. This application works fine in Visual Studio 2015 on Windows 7. However, it gives an error when running in code blocks on Ubuntu Linux. I have replicated the error message I get using the following simple Person class.

Error message: 'comparePersonAge' was not declared in this scope

Person.h

 #ifndef Person_h #define Person_h #include <string> class Person { private: int age; std::string name; public: Person(int a, std::string n) : age(a), name(n) {} int getAge() { return age; } std::string getName() { return name; } inline friend bool comparePersonAge(const Person& p1, const Person& p2) { return p1.age < p2.age; } }; #endif 

main.cpp

 #include <iostream> #include <algorithm> #include <vector> #include "Person.h" int main() { Person p1(93, "harold"); Person p2(32, "james"); Person p3(67, "tracey"); std::vector<Person> v; v.push_back(p1); v.push_back(p2); v.push_back(p3); std::sort(v.begin(), v.end(), comparePersonAge); std::cout << v[0].getAge() << " " << v[1].getAge() << " " << v[2].getAge() << std::endl; } 

On a Windows computer, output: 32 67 93 , as expected. On Linux, the error message is listed above.

Note. . Someone else, the name DJR, discusses this issue in this post: Friend function not declared in this scope error. . However, his explanation is very vague and does not follow his steps.

He's writing:

Previous comment should be read: This is a bug on the Linux side. The code should work as it is written. I have code right now that compiles on the Windows side, and when I switch to the Linux side, I get the same error. Apparently, the compiler that you use on the Linux side does not see / do not use the friend declaration in the header file and therefore gives this error. Just translating the friend function definition / implementation into a C ++ file before using this function (for example, how one could use it when assigning a callback function), this fixed my problem and also solved your problem.

I don't know what it means by moving the friend function definition in the C ++ file until the function is used. What does it mean?

+5
source share
3 answers

The purpose of the friend keyword is to make an exception for access rules ( protected and private ) by giving a class or function access to members that are not otherwise authorized.

That way, you can declare and define your comparePersonAge() function outside of your class declaration and use the friend keyword inside the declaration to give the function access to private members of age .

+1
source

Standard 7.3.1.2/3:

Each name that is first declared in a namespace is a member of this namespace. If a friend declaration in a non-local class first declares a class or function, the friend's class or function is a member of the internal namespace. Friend's name was not found unconditional search (3.4.1) or qualified search (3.4.3), while in this area of ​​the namespace (either before or after the definition of the class that gives friendship). If a friend calls a function, its name can be found by a name that considers functions from namespaces and classes associated with function argument types (3.4.2) . If the name in the other declaration is neither qualified nor the identifier of the template, and the declaration is a function or a specified type specifier, the search to determine whether the object was previously declared does not consider areas outside the innermost encompassing namespace.

Well, after a short discussion with @Niall, I realized that MSVC ++ is not so in this case, since ADL only happens in the function call expression, and since std::sort is passed only the function name, i.e. comparePersonAge , the comparePersonAge function should be found during calling std::sort . Therefore, GCC and Clang are true, I think

+1
source

A few points.

  • There is no need to specify inline if it is defined in the class.
  • Although this declaration provides a friend function that is a member of the class's encompassing namespace until it is explicitly declared in that namespace, it is not available for regular searches - although ADL is allowed.

So, if you want to make it accessible through a regular search, declare it in the encompassing namespace.

Demo

0
source

Source: https://habr.com/ru/post/1243241/


All Articles