我正在使用一个在全局命名空间中定义输出流运算符 (operator<)>)>
这里有一个简单的例子来说明我的问题:
#include <iostream>
namespace A
{
struct MyClass {};
}
std::ostream & operator<<( std::ostream & os, const A::MyClass & )
{ os << "namespace A"; return os; }
namespace B
{
struct MyClass {};
std::ostream & operator<<( std::ostream & os, const B::MyClass & )
{ os << "namespace B"; return os; }
}
namespace B
{
void Test()
{
std::cout << A::MyClass() << std::endl;
std::cout << B::MyClass() << std::endl;
}
}
int main()
{
B::Test();
return 1;
}
我收到以下错误:
error: no match for ‘operator<<’ in ‘std::cout << A::MyClass()’
请注意,如果两个运算符都在命名空间中,或者如果它们都在全局命名空间中,则代码可以正确编译和执行。
我真的很想了解发生了什么,以及使用命名空间定义此类运算符的“良好做法”。
谢谢!
最佳答案
自从 Test位于命名空间 B编译器在该命名空间中看到该运算符,并指出它没有匹配的签名。它还尝试在 namespace A 中找到包含该类但也找不到该类的运算符。因为命名空间B 中已经有这样的运算符(签名错误)它不会去尝试在全局范围内找到一个。
它不搜索全局的原因大致如下。我先引用标准,然后再解释一下。
从 3.4/1 开始:
...Name lookup may associate more than one declaration with a name if it finds the name to be a function name; the declarations are said to form a set of overloaded functions (13.1). Overload resolution (13.3) takes place after name lookup has succeeded.
当我读到这篇文章时,当编译器试图找到一个函数(你的操作符在这个上下文中)时,它首先会尝试进行名称查找以首先找到该函数。然后接下来它会尝试从重载集中选择正确的函数。
现在从 3.4.1/6 开始:
A name used in the definition of a function(26) that is a member of namespace N (where, only for the purpose of exposition, N could represent the global scope) shall be declared before its use in the block in which it is used or in one of its enclosing blocks (6.3) or, shall be declared before its use in namespace N or, if N is a nested namespace, shall be declared before its use in one of N’s enclosing namespaces.
让我们分解一下。您正在使用 operator<<在命名空间级别函数中,因此本节适用。它将尝试使用上述优先级来查找该运算符。您的运算符未在当前 block 或封闭 block 中声明(这是指嵌套在您的函数中的 {})。然而,下一部分匹配“...shall be declared before its use in namespace N...”。 有实际上是一个operator<<在当前命名空间( B )中,因此它将该运算符添加到其匹配列表中。 B 中没有更多匹配项,并且由于相同命名空间范围被认为是最佳匹配接近度,因此它不会查看任何其他范围。
将操作符放入命名空间 A 时它起作用的原因是因为正在打印的项目是 A 的成员,实际上考虑了该命名空间,因为它包含在表达式的命名空间中。自命名空间 A 认为它在该命名空间中找到了适当的匹配项并正确编译。
现在它有一个可能的运算符列表,它会尝试对它们进行重载决策。不幸的是,在命名空间 B 中找到的那个是它唯一考虑的那个,它与所需的参数不匹配。
一般来说,插入操作符应该与它所操作的类在同一个命名空间中。
关于c++ - 命名空间和运算符解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5195512/
我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我正在使用ruby1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是
当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?
我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use
简而言之错误:NOTE:Gem::SourceIndex#add_specisdeprecated,useSpecification.add_spec.Itwillberemovedonorafter2011-11-01.Gem::SourceIndex#add_speccalledfrom/opt/local/lib/ruby/site_ruby/1.8/rubygems/source_index.rb:91./opt/local/lib/ruby/gems/1.8/gems/rails-2.3.8/lib/rails/gem_dependency.rb:275:in`==':und
如何将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.你能做的最好的事情是:
我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty