C++ Primer 说:
It is important to understand that a friend declaration affects access but is not a declaration in an ordinary sense.
所以友元声明应该只提供对友元类/函数的访问权限,它不是真正的声明。
但是,我试过这个程序,它编译成功并在 GCC 5.2.0 中输出 2,有什么问题吗?
#include <iostream>
class Tmp {
public:
Tmp(int a) : a_(a) {};
private:
int a_;
friend void p(Tmp a) { std::cout << a.a_ << std::endl; }
};
// void p(Tmp a); I commented it, so there is not any declaration statement for p(Tmp a).
int main(void) {
Tmp a(2);
p(a);
return 0;
}
最佳答案
友元声明是技术意义上的真正声明:它是根据 C++ 语言语法的声明。关键字 friend 是修饰声明的说明符。
如果你真的想知道这本书的意思,你应该只看前面的文字。
Classes and nonmember functions need not have been declared before they are used in a friend declaration. When a name first appears in a friend declaration, that name is implicitly assumed to be part of the surrounding scope. However, the friend itself is not actually declared in that scope (§7.2.1, p. 270).
Even if we define the function inside the class, we must still provide a declaration outside the class itself to make that function visible. A declaration must exist even if we only call the friend from members of the friendship granting class.
友元声明与典型声明不同,因为大多数声明将它们声明的名称引入它们所在的范围,然后这些名称可能会立即被使用:
int x; // introduces the name x into this scope
x = 0; // lookup of "x" finds the name just declared
友元声明将声明的名称引入最近的封闭命名空间,而不是友元声明所在的类。所以从这个意义上说这是不寻常的。然而,更不寻常的是,在最近的封闭范围内声明相同的名称之前,友元声明引入的名称对于限定名称或非限定名称查找不可见。
换句话说,您可能无法在好友声明后立即开始使用该名称。书上说 friend 声明不是一般意义上的声明大概就是这个意思吧。
这是一个简单的例子:
#include <cstdio>
class C {
friend void hello() { std::puts("Hello, world!"); }
};
int main() {
hello();
}
此程序格式错误,因为 hello 在调用之前未在全局命名空间中声明。 http://coliru.stacked-crooked.com/a/3ae525122312c96c
你的例子只是碰巧起作用,因为有一个特殊的规则,即依赖于参数的查找查找在关联类内声明的 friend ,即使它们尚未在命名空间范围内声明。在调用 p(a) 中,由于 a 具有类类型 Tmp,因此类 Tmp 是关联的类。
关于c++ - 好友声明是真实的声明吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32175304/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我正在使用active_admin,我在Rails3应用程序的应用程序中有一个目录管理,其中包含模型和页面的声明。时不时地我也有一个类,当那个类有一个常量时,就像这样:classFooBAR="bar"end然后,我在每个必须在我的Rails应用程序中重新加载一些代码的请求中收到此警告:/Users/pupeno/helloworld/app/admin/billing.rb:12:warning:alreadyinitializedconstantBAR知道发生了什么以及如何避免这些警告吗? 最佳答案 在纯Ruby中:classA
我有一个应用程序可以读取文件的内容并为其编制索引。我将它们存储在磁盘本身中,但现在我使用的是AmazonS3,因此以下方法不再适用。事情是这样的:defperform(docId)@document=Document.find(docId)if@document.file?#Youshould'tcreateanewversion@document.versionlessdo|doc|@document.file_content=Cloudoc::Extractor.new.extract(@document.file.file)@document.saveendendend@docu
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“
有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=
出于某种原因,heroku尝试要求dm-sqlite-adapter,即使它应该在这里使用Postgres。请注意,这发生在我打开任何URL时-而不是在gitpush本身期间。我构建了一个默认的Facebook应用程序。gem文件:source:gemcuttergem"foreman"gem"sinatra"gem"mogli"gem"json"gem"httparty"gem"thin"gem"data_mapper"gem"heroku"group:productiondogem"pg"gem"dm-postgres-adapter"endgroup:development,:t
我正在学习Ruby,遇到了inject。我正处于理解它的风口浪尖,但当我是那种需要真实世界的例子来学习一些东西的人时。我遇到的最常见的例子是人们使用inject来添加一个(1..10)范围的总和,我不太关心这个。这是一个任意的例子。在实际程序中我会用它做什么?我正在学习,所以我可以继续使用Rails,但我不必有一个以Web为中心的示例。我只需要一些我可以全神贯注的目标。谢谢大家。 最佳答案 inject有时可以通过它的“其他”名称reduce更好地理解。它是一个对Enumerable进行操作(迭代一次)并返回单个值的函数。它有许多有
我有一个ruby程序,我想接受用户创建的方法,并使用该名称创建一个新方法。我试过这个:defmethod_missing(meth,*args,&block)name=meth.to_sclass我收到以下错误:`define_method':interningemptystring(ArgumentError)in'method_missing'有什么想法吗?谢谢。编辑:我以不同的方式让它工作,但我仍然很好奇如何以这种方式做到这一点。这是我的代码:defmethod_missing(meth,*args,&block)Adder.class_evaldodefine_method