繁体   English   中英

课堂上的朋友运算符似乎没有参与重载解析

[英]In-class friend operator doesn't seem to participate in overload resolution

在编写CRTP模板以使类能够基于模板参数为operator+提供重载时,我发现,如果一个类中的Friend运算符的参数都不属于其类型,则似乎不参与重载解析。定义于

归结为:

enum class FooValueT{
    zero, one, two
};

class Foo{
    FooValueT val_;
public:
    Foo(FooValueT x) : val_(x){};

    Foo& operator+=(Foo other){
        val_ = (FooValueT)((int)val_ + (int)other.val_);
        return *this;
    }

    //overload for Foo+Foo, FooValueT+Foo and Foo+FooValueT
    friend Foo operator+(Foo lhs, Foo rhs){
        Foo ret = lhs;
        return ret += lhs;
    }

    //explicit overload for FooValueT+FooValueT
    friend Foo operator+(FooValueT lhs, FooValueT rhs){
        return (Foo)lhs + (Foo)rhs;
    }
};

看起来有点多余,但是因为Foo my = FooValueT::one + FooValueT::zero;是必要的Foo my = FooValueT::one + FooValueT::zero; 应该是一个有效的表达式,并且如果所有参数都不具有class-type,则不会隐式转换它们,如对我的上一个问题的回答中所述。

尽管进行了所有这些努力,但以下代码仍无法编译:

int main(int argc, char* argv[])
{
    Foo my = FooValueT::zero;
    my += FooValueT::one;
    my = Foo(FooValueT::zero) + FooValueT::two;
    my = FooValueT::zero + Foo(FooValueT::two);
    my = FooValueT::zero + FooValueT::two; //error C2676
    return 0;
}

错误消息是:

error C2676: binary '+' : 'FooValueT' does not define this operator or a conversion to a type acceptable to the predefined operator

一旦我将运算符完全移出类,或将其声明为好友,但在类外定义了它,此问题就解决了。 Foo是要派生的模板类时,两者似乎都不是可行的选择。

据我所知,上面的operator+(ValueT,ValueT)的类内朋友定义应该创建一个自由函数,就像该定义一样:

class Foo{
/*All the stuff you saw previously*/
    friend Foo operator+(FooValueT lhs, FooValueT rhs);
};

Foo operator+(FooValueT lhs, FooValueT rhs){
    return (Foo)lhs + (Foo)rhs;
}

我在哪里错了? 与常规的免费好友功能相比,类内好友功能定义是否会更改重载解析规则?

n3376 11.3 / 6-7

当且仅当该类是非本地类(9.8),函数名称不合格且该函数具有名称空间范围时,才可以在该类的朋友声明中定义一个函数。

此类函数是隐式内联的。 在类中定义的朋友功能在其定义的类的(词法)范围内。 在类之外定义的朋友函数不是(3.4.1)。

在您的情况下,运算符在类作用域中,并且当您尝试调用该运算符时,ADL不会尝试在类中查找运算符,因为这两个参数都不具有此类的类型。 只需编写自由函数(或在类中没有声明的朋友)。

好像您不能做这样的事情,在类中声明friend函数的问题是该函数将在class-scope中,但是您不能将此函数声明为免费的friend函数,因为编译器无法推断出return-type参数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM