我正在将所有C ++ Windows应用程序移动到Ubuntu Linux。此应用程序在Windows 7操作系统上的Visual Studio 2015社区上运行良好。但是,在Ubuntu Linux上的代码块中运行时会出错。我使用以下简单的Person
类复制了我收到的错误消息。
错误消息:未在此范围内声明'comparePersonAge'
#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;
}
在Windows计算机上,输出为:32 67 93
按预期方式。在Linux上,错误消息如上所示。
注意:其他人的名字DJR在这篇文章中讨论了这个问题:Friend function not declared in this scope error。 但是,他的解释非常模糊,不遵循他的步骤。
他写道:
以前的评论应该是:这是Linux方面的一个错误。代码应该按照书面形式工作。我现在有代码在Windows端编译很好,当我将它移动到Linux端时,我得到相同的错误。显然,你在Linux端使用的编译器没有在头文件中看到/使用friend声明,因此给出了这个错误。通过简单地在C ++文件中移动友元函数的定义/实现BEFORE函数的用法(例如:可能在函数回调赋值中使用),这解决了我的问题并且也应解决你的问题。
我不知道在函数使用之前在C ++文件中移动友元函数的定义意味着什么。这究竟意味着什么?
答案 0 :(得分:1)
friend
关键字的目的是对访问规则(protected
和private
)进行例外处理,为不允许的成员提供类或函数访问权。
因此,您可以在类声明之外声明和定义comparePersonAge()
函数,并在声明中使用friend
关键字,以使函数能够访问私有成员,age
具体
答案 1 :(得分:1)
标准7.3.1.2/3:
首先在名称空间中声明的每个名称都是其中的一员 命名空间。 如果非本地类中的朋友声明首先声明 朋友类或函数所属的类或函数 最里面的封闭命名空间。找不到朋友的名字 非限定查找(3.4.1)或通过限定查找(3.4.3)直到a 在该命名空间范围内提供匹配声明(或者 在授予友谊的类定义之前或之后)。如果是朋友 函数被调用,其名称可以通过名称查找找到 考虑来自名称空间和与之关联的类的函数 函数参数的类型(3.4.2)。如果是朋友的名字 声明既不是合格的,也不是模板ID和声明 是一个函数或一个精心设计的类型说明符,用于确定的查找 该实体是否先前已被宣布不得考虑任何实体 最内层封闭命名空间之外的范围。
好的,在与@Niall讨论之后我意识到MSVC ++在这种情况下是错误的,因为ADL只发生在函数调用表达式中,并且因为std::sort
只传递函数名称即comparePersonAge
,所以没有在致电comparePersonAge
时应找到函数std::sort
。因此,我认为GCC和Clang是正确的
答案 2 :(得分:0)
有几点。
inline
,则无需指定 $parent = array(
array(//$parent[0]
"a-key",
"b-key" => array(
array("1", "2", "3"), //b-key[0]
array("4", "5", "6")) //b-key[1]
,
"c-key"),
array(//$parent[1]
"a-key",
"b-key" => array(array("7", "8", "9"), //b-key[0]
array("10", "16", //b-key[1]
"12" => array(array("13"), //12[0]
array("14"))), //12[1]
array("15", "16" => array(), "17")) //b-key[2]
,
"c-key"),
array(//$parent[2]
"a-key",
"b-key" => array(array("7", "8", "9"), //b-key[0]
array("10", "16", //b-key[1]
"12" => array(array("13"), //12[0]
array("14"))), //12[1]
array("15", "16" => array(), "17")) //b-key[2]
,
"c-key")
);
。因此,如果您想通过常规查找使其可访问,请在封闭的命名空间中声明它。