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

冷暖自知 提交于 2019-12-13 13:06:21

问题


I am in the process of moving all of my C++ Windows applications to Ubuntu Linux. This application runs fine on Visual Studio 2015 Community on Windows 7 OS. However, it gives an error when running in Code Blocks on Ubuntu Linux. I have replicated the error message I am getting 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 Windows machine, the output is: 32 67 93 as expected. On Linux, the error message is as written above.

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

He writes:

Previous comment should have read: It is a bug on the the Linux side. The code should work as written. I have code right now that compiles fine on the Windows side and when I move it to the Linux side I get the same error. Apparently the compiler that you are using on the Linux side does not see/use the friend declaration in the header file and hence gives this error. By simply moving the friend function's definition/implementation in the C++ file BEFORE that function's usage (e.g.: as might be used in function callback assignment), this resolved my issue and should resolve yours also.

I don't know what he means by by moving the friend function's definition in the C++ file before the function's usage. What does this mean precisely?


回答1:


The purpose of the friend keyword is to make an exception to the access rules (protected and private), giving a class or function access to members not otherwise allowed.

So 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, age specifically.




回答2:


Standard 7.3.1.2/3 :

Every name first declared in a namespace is a member of that namespace. If a friend declaration in a non-local class first declares a class or function the friend class or function is a member of the innermost enclosing namespace. The name of the friend is not found by unqualified lookup (3.4.1) or by qualified lookup (3.4.3) until a matching declaration is provided in that namespace scope (either before or after the class definition granting friendship). If a friend function is called, its name may be found by the name lookup that considers functions from namespaces and classes associated with the types of the function arguments (3.4.2) . If the name in a friend declaration is neither qualified nor a template-id and the declaration is a function or an elaborated-type-specifier, the lookup to determine whether the entity has been previously declared shall not consider any scopes outside the innermost enclosing namespace.

Ok after little discussion with @Niall I realized that MSVC++ is wrong in this case, since ADL only happens in function call expression and since std::sort is being passed just name of function i.e comparePersonAge, no function comparePersonAge should be found at the time of call to std::sort . Hence GCC and Clang are correct I think




回答3:


A couple of points.

  1. There's no need to specify inline if it's defined within the class.
  2. Although that declaration yields a friend function which is a member of the enclosing namespace of the class, until it's declared in that namespace explicitly, it's not available for regular lookup—though ADL is allowed.

So if you want to make it accessible via regular lookup, declare it in the enclosing namespace.

Demo



来源:https://stackoverflow.com/questions/35463169/error-friend-member-function-name-was-not-declared-in-this-scope

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!