我正在研究一些旧的库代码,其基本目标是重构它。这段旧代码并不完全符合最佳实践和美观(是的 - friend 是坏人,在发现以下内容后已将其删除 - 因为它是重构中的疏忽)。
现在准备运行一些单元测试,我用 clang++、g++ 和 vc++ 编译了代码(2005 - 是的,我知道它很旧,但为了向后兼容 - 我必须这样做)。
g++ 和 clang++ 编译和运行没有错误,但是 Visual C++ 报错,所以在查看代码后,我发现了一些类似的东西:
#include <iostream>
class one {
private:
struct private_impl;
private_impl* pimpl_;
public:
one();
~one();
void say_hello();
};
class two {
private:
friend class one;
void say_world();
public:
};
struct one::private_impl {
two t;
void say_world();
};
void one::private_impl::say_world() {
std::cout << " ";
t.say_world(); //This should not work should it?
}
one::one() : pimpl_(new private_impl) { }
one::~one() {
delete pimpl_;
}
void one::say_hello() {
std::cout << "Hello";
pimpl_->say_world();
std::cout << std::endl;
}
void two::say_world() {
std::cout << "World";
}
int main() {
one test;
test.say_hello();
return 0;
}
使用开关编译(g++ 和 clang++):
-Wall -Wextra -pedantic
clang++ version: 3.3
g++ version: 4.8.2
现在 Visual C++ 提示 private_impl::say_world() 无法访问类二的私有(private)成员。在查看了 c++ friend 规则后,对我来说,这是正确的——但我对此的理解是错误的吗?我是否误读了信息(英语不是我的母语)?
根据标准(c++03 - 我现在手头没有 c++11):
The members of a nested class have no special access to members of an enclosing class, nor to classes or functions that have granted friendship to an enclosing class; the usual access rules (clause 11) shall be obeyed. The members of an enclosing class have no special access to members of a nested class; the usual access rules (clause 11) shall be obeyed.
还有这个:
Friendship is neither inherited nor transitive.
所以我的基本问题 - 谁才是真正正确的 - clang 和 gcc 或 vc++?
此外 - 这个问题只是出于对此事的好奇,并试图更好地了解这个世界。
最佳答案
周围类成员的可访问性受CWG 45影响。 .这意味着,至少部分问题已被归类为 C++98 标准中的缺陷。 (好像在2001年就提出了解决方案,所以我不太明白为什么在C++03中还没有修复。)
在C++11中,合并了解析,所以段落改为[class.access.nest]/1:
A nested class is a member and as such has the same access rights as any other member. The members of an enclosing class have no special access to members of a nested class; the usual access rules shall be obeyed. [Example:
class E { int x; class B { }; class I { B b; // OK: E::I can access E::B int y; void f(E* p, int i) { p->x = i; // OK: E::I can access E::x } }; int g(I* p) { return p->y; // error: I::y is private } };— end example]
(一些)建议的缺陷解决方案在编译器中实现;注意g++ for example specifically says -std=c++03 标志表示
The 1998 ISO C++ standard plus the 2003 technical corrigendum and some additional defect reports.
所以使用这个标志时你得到的结果并不明显。然而,DR 是“委员会意图的指示”,因此它们可以被视为标准中的“错误”,应该被修复。
VC++2005 似乎没有按照原始标准执行建议的解决方案。
关于c++ - 内部类、pimpl 和一个 friend 类——不同意的编译器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21134306/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
如何将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.你能做的最好的事情是:
我基本上来自Java背景并且努力理解Ruby中的模运算。(5%3)(-5%3)(5%-3)(-5%-3)Java中的上述操作产生,2个-22个-2但在Ruby中,相同的表达式会产生21个-1-2.Ruby在逻辑上有多擅长这个?模块操作在Ruby中是如何实现的?如果将同一个操作定义为一个web服务,两个服务如何匹配逻辑。 最佳答案 在Java中,模运算的结果与被除数的符号相同。在Ruby中,它与除数的符号相同。remainder()在Ruby中与被除数的符号相同。您可能还想引用modulooperation.
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
RSpec似乎按顺序匹配方法接收的消息。我不确定如何使以下代码工作:allow(a).toreceive(:f)expect(a).toreceive(:f).with(2)a.f(1)a.f(2)a.f(3)我问的原因是a.f的一些调用是由我的代码的上层控制的,所以我不能对这些方法调用添加期望。 最佳答案 RSpecspy是测试这种情况的一种方式。要监视一个方法,用allowstub,除了方法名称之外没有任何约束,调用该方法,然后expect确切的方法调用。例如:allow(a).toreceive(:f)a.f(2)a.f(1)
A/ctohttp://wiki.nginx.org/CoreModule#usermaster进程曾经以root用户运行,是否可以以不同的用户运行nginxmaster进程? 最佳答案 只需以非root身份运行init脚本(即/etc/init.d/nginxstart),就可以用不同的用户运行nginxmaster进程。如果这真的是你想要做的,你将需要确保日志和pid目录(通常是/var/log/nginx&/var/run/nginx.pid)对该用户是可写的,并且您所有的listen调用都是针对大于1024的端口(因为绑定(
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么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代码中:ModuleMClassC当我尝试运行时出现“'M:Module'的未定义方法'helper'”错误c=M::C.new("world")c.work但直接从另一个类调用M::helper("world")工作正常。类不能调用在定义它们的同一模块中定义的模块函数吗?除了将类移出模块外,还有其他解决方法吗? 最佳答案 为了调用M::helper,你需要将它定义为defself.helper;结束为了进行比较,请查看以下修改后的代码段中的helper和helper2moduleMclassC
有没有办法在sinatra的beforedoblock中停止执行并返回不同的值?beforedo#codeishere#Iwouldliketo'return"Message"'#Iwouldlike"/home"tonotgetcalled.end//restofthecodeget'/home'doend 最佳答案 beforedohalt401,{'Content-Type'=>'text/plain'},'Message!'end如果你愿意,你可以只指定状态,这里有状态、标题和正文的例子
我想用sunspot重现以下原始solr查询q=exact_term_text:fooORterm_textv:foo*ORalternate_text:bar*但我无法通过标准的太阳黑子界面理解这是否可能以及如何实现,因为看起来:fulltext方法似乎不接受多个文本/搜索字段参数我不知道将什么参数作为第一个参数传递给fulltext,就好像我通过了"foo"或"bar"结果不匹配如果我传递一个空参数,我得到一个q=*:*范围过滤器(例如with(:term).starting_with('foo*')(顾名思义)作为过滤器查询应用,因此不参与评分。似乎可以手动编写字符串(或者可能使