我试图在命名空间之外定义一个类朋友函数,如下所示:
namespace A{
class window{
    private:
    int a;
    friend void f(window);
};
}
 void f(A::window rhs){
 cout << rhs.a << endl;
}
我得到一个错误说有歧义.有两个候选人void A::f(A::window);和void f(A::window).所以我的问题是:
1)如何使全局函数void f(A::window rhs)成为类A :: window的朋友.
编辑:(阅读答案后)
2)为什么我需要通过操作来限定窗口类中的成员函数f是全局的::f(window)?
3)为什么我需要在这种特殊情况下预先声明函数f(A :: window),而当该类不是在命名空间中定义时,它是在函数被声明为朋友之后声明的函数的okey.
在GCC中,您可以通过获取标签的地址(如在)中然后跳转到它()来使用计算的goto.在GCC手册说,你可以从任何地方在功能跳转到这个地址,它只是跳转到它从另一个功能是不确定的.void *addr = &&labeljump *addr
当你跳转到代码时,它不能假设任何关于寄存器值的东西,所以可能它会从内存中重新加载它们.但是,堆栈指针的值也不一定定义,例如,您可能从声明额外变量的嵌套范围跳转.
问题是GCC如何设置将堆栈指针的值设置为正确的值(可能太高或太低)?-fomit-frame-pointer它是如何与之相互作用的(如果有的话)?
最后,对于额外的点,你可以从哪里跳到标签的真正限制是什么?例如,您可以从中断处理程序执行此操作.
我有一个像Person这样简单的类似于值的类:
class Person
{
public:
    Person(ThirdPartyClass *object);
    virtual ~Person(void);
    virtual std::string GetFullName() const;
    virtual int GetAge() const;
    virtual int GetNumberOfDaysTillBirthday() const;
};
我正在使用第三方库,ThirdPartyClass需要有一个名为Destroy(第三方库的一部分)的全局/静态函数来调用它来销毁它.Destroy在Person析构函数中调用此函数.
现在我正在尝试对我的Person类进行单元测试,我需要一种模拟/存根Destroy方法的方法.我想我可以围绕静态Destroy函数编写一个包装类,然后使用依赖注入将这个包装器注入到Person类中,但这样做只是为了在这个简单的类上调用这个函数似乎有些过分.什么是简单直接的方法呢?或者依赖注入真的是最好的方法吗?
更新
最终我决定创建一个包含所有第三方库的全局函数的类,然后使用依赖注入将此类传递给我的person类的构造函数.这样我就可以删除Destroy方法.虽然person类只使用单个函数,但是在我的代码中的其他点调用库的其他函数,因为我需要测试那些我将面临同样问题的函数.
我在主应用程序代码中创建了这个包装类的单个实例,并在需要的地方注入它.我选择走这条路是因为我觉得它更清楚.我喜欢Billy ONeal的解决方案,我认为它回答了我的问题,但我意识到如果我要将代码保留几个月并且回来,我会花更长的时间来弄清楚与依赖注入相比发生了什么.我想起了蟒蛇格言的禅语"明确比隐含更好".而且我觉得依赖注入使得发生的事情变得更加明确.
我正在尝试序列化对象,通过仅使用STL的套接字通过网络发送.我没有找到一种方法来保持对象的结构在其他主机中反序列化.我试过转换到string,char*并且我花了很长时间在互联网上搜索教程,直到现在我什么都没发现.
有没有办法只用STL做到这一点?
有没有好的教程?
我差点尝试提升,但如果有STL怎么做我想学习.
如果我有一个类Base,至少有一个虚函数,并且一个Derived类从中单独继承,(uintptr_t)derived - (uintptr_t)static_cast<Base*>(derived)则保证(由Itanium ABI)为零,即使Derived不是标准布局.然而,在一般情况下,这不一定是真的(例如,多重继承).
是否有可能编写一个特征,可用于检测一个类是否是另一个类的主要基类?
来自Itanium ABI的有用部分:
http://refspecs.linux-foundation.org/cxxabi-1.83.html
主要基类
对于动态类,它与偏移0共享虚拟指针的唯一基类(如果有).它是第一个(以直接基类顺序排列)非虚拟动态基类(如果存在).
动态类
需要虚拟表指针的类(因为它或其基数具有一个或多个虚拟成员函数或虚拟基类).
我有一个函数,可以通过通用引用接受任何类型,并希望为特定类型重载它(其中一些是自己模板化的,虽然我不认为这在这里很重要).不幸的是,我似乎无法以正确的顺序解决重载问题.
我会假设第二个声明会更受欢迎,foo因为它更具体(模板化程度更低),尽管看起来我对重载决策的理解有些缺乏.有趣的是,将第二个声明更改为X值,使得它打印"好,好"并且X通过非const引用使其打印"坏,好".显然,删除第一个声明会使它返回"好,好",因为没有其他选择.
那么为什么会这样呢?最重要的是,如果以下代码不起作用,如何使用此签名重载函数?
#include <iostream>
#include <string>
class X {};
template<typename T>
inline std::string foo(T && rhs) {
    return "bad";
}
inline std::string foo(const X & rhs) {
    return "good";
}
int main() {
    std::cout << foo(X()) << std::endl;
    X x;
    std::cout << foo(x) << std::endl;
    return 0;
}
编辑:
也许更迂回的解决方案是间接地做到这一点.摆脱第一种形式foo并使用SFINAE检查是否存在有效的过载,然后它不会调用foo_fallback.
我正在研究嵌入式平台(ARM),在处理位模式时必须小心.让我们假装这条线超出了我的影响力:
uint8_t foo = 0xCE;          // 0b11001110
解释为无符号,这将是206.但实际上它是签名的,因此类似于-50.如何继续使用此值作为签名?
int8_t bar = foo;            // doesn't work
两者都没有(导致所有输入值的0x10或0x00)
int8_t bar = static_cast<int8_t>(foo);
int8_t bar = reinterpret_cast<int8_t&>(foo);
我只是希望这些位保持不变,即. (bar == 0xCE)
反之亦然我感兴趣的是如何将代表负数的位模式转换为无符号变量而不会弄乱位模式.我正在使用GCC.
如果我们在c ++中有以下2个代码片段来执行相同的任务:
int a, b=somenumber;
while(b > 0)
{
a = b % 3;
b /= 3;
}
要么
int b=somenumber;
while(b > 0)
{
int a=b%3;
b /= 3;
}
我对计算机体系结构/ c ++设计了解不多,但我认为第一个代码更快,因为它在开始时声明了整数a并且只在while循环中使用它,而在第二个代码中,整数a是每次while循环重新开始时都被声明.有人可以帮我这个,我是正确的还是为什么?为什么?
关于这个代码,我有两个问题:
namespace A { class window; }
void f(A::window);
namespace A
{
    class window
    {
    private:
       int a;
       friend void ::f(window);
    };
}
void f(A::window rhs)
{
    std::cout << rhs.a << std::endl;
}
1)为什么我需要通过执行:: f(window)来限定窗口类中的成员函数f是全局的?
2)为什么我需要在这种特殊情况下预先声明函数f(A :: window),而当在类名称空间内没有定义类时,可以在函数声明为朋友之后声明函数.
以下代码不起作用,因为您不能static_cast从私有基类.
用C样式转换工程的更换演员(虽然我原本以为这会发生未定义行为,显然这不,看到这个答案),但是是比较难看,因为它也可以让你绕过const的检查等.另一种方法将CRTPBase作为朋友,但这会暴露所有Derived的私人成员.
有没有另外一种方法来编写这个没有使用C风格的演员而没有让CRTPBase成为朋友?
template<typename T>
struct CRTPBase {
    void callBase() {
        T * derived = static_cast<T*>(this);
        derived->publicMethod();
    }
};
struct Derived : private CRTPBase<Derived> {
    void callParent() { this->callBase(); }
    void publicMethod() {}
};
int main() {
    Derived d;
    d.callParent();
    return 0;
}
c++ ×9
friend ×2
namespaces ×2
c ×1
c++11 ×1
embedded ×1
function ×1
gcc ×1
goto ×1
itanium-abi ×1
linux ×1
mocking ×1
overloading ×1
sockets ×1
stack ×1
static-cast ×1
stream ×1
type-traits ×1
unit-testing ×1
vptr ×1