朋友们,操作符关键字和作用域解析

4
namespace GameForge
{
    namespace Core
    {
        class CTribool;
    }
}

GameForge::Core::CTribool operator ! ( const GameForge::Core::CTribool& rkTribool );

namespace GameForge
{
    namespace Core
    {
        class CTribool
        {
            friend CTribool operator ! ( const CTribool& rkTribool );

        private:
            EState m_eState;
        };
    }
}


GameForge::Core::CTribool operator ! ( const GameForge::Core::CTribool& rkTribool )
{
    switch( rkTribool.m_eState )
        {
    // Some stuff...

因为m_eState在最后一个定义中不可访问,所以无法编译。原因是友元声明出现在CTribool命名空间中,因此声明了一个不同的函数。因此,我尝试使用作用域解析运算符,如下所示。

friend CTribool ::operator ! ( const CTribool& rkTribool );

并且

friend CTribool ::( operator ! ) ( const CTribool& rkTribool );

但是这也行不通,因为某种原因CTribool没有被识别为有效类型。 我怀疑在这种情况下前向声明是不够的。有什么解决方法吗?


1
并不是CTribool未被识别为有效类型。当您在friend声明中使用限定名称时,必须引用已经声明的内容。 - Angew is no longer proud of SO
有没有办法实现我想做的事情?我的意思是,如果存在某种循环依赖关系 (CTribool 运算符 -> CTribool -> 与运算符的友元),那该怎么办? - Adrian Goudard
不要使用 C 作为类的前缀,这从来都不是合适的做法,而且只是基于对 MFC 命名约定的误解。 - Konrad Rudolph
2个回答

1
你应该在与CTribool类相同的命名空间中定义你的运算符。这是正确的做法;它将在应用程序中通过ADL被找到:
namespace GameForge
{
    namespace Core
    {
        class CTribool
        {
            friend CTribool operator ! ( const CTribool& rkTribool );

        private:
            EState m_eState;
        };
    }
}



namespace GameForge
{
    namespace Core
    {
        CTribool operator ! ( const GameForge::Core::CTribool& rkTribool )
        {
            switch( rkTribool.m_eState )
                {
                // Some stuff...
                }
        }
    }
}

1
奇怪的是,你需要这样做:

Strangely enough, you need to do this:

        friend CTribool (::operator !) ( const CTribool& rkTribool );

你需要指定函数在全局作用域中,但是如果没有括号,你的::会与CTribool绑定,就像这样:
        friend (CTribool::operator !) ( const CTribool& rkTribool );

在这种情况下,它会认为你正在指定一个没有返回类型的函数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接