不能有汽车朋友

发布于 2024-11-04 22:50:26 字数 779 浏览 1 评论 0原文

    struct X
    {

    private:
        int value_;
    public:
        X():value_(int())
        {}
        X(int value):value_(value)
        {}
        friend
            //int operator+(X lhs, X rhs);//THIS WILL WORK  
//BUT THE ONE BELOW WON'T
        auto operator+(const X& lhs, const X& rhs)->decltype(lhs.value_ + rhs.value_);

    };


    auto operator+(const X& lhs, const X& rhs)->decltype(lhs.value_ + rhs.value_)
    {//If I change return type to "not auto" there is no problem with friendship
        return lhs.value_ + rhs.value_;
    }

    int main(int argc, char* argv[])
    {
        X a(5);
        X b(6);
        cout << a + b;
        return 0;
    }

当返回类型为auto时,无法声明与operator+的友谊。有什么解决办法吗?

    struct X
    {

    private:
        int value_;
    public:
        X():value_(int())
        {}
        X(int value):value_(value)
        {}
        friend
            //int operator+(X lhs, X rhs);//THIS WILL WORK  
//BUT THE ONE BELOW WON'T
        auto operator+(const X& lhs, const X& rhs)->decltype(lhs.value_ + rhs.value_);

    };


    auto operator+(const X& lhs, const X& rhs)->decltype(lhs.value_ + rhs.value_)
    {//If I change return type to "not auto" there is no problem with friendship
        return lhs.value_ + rhs.value_;
    }

    int main(int argc, char* argv[])
    {
        X a(5);
        X b(6);
        cout << a + b;
        return 0;
    }

Cannot declare a friendship with operator+ in scenario when return type is auto. Any solution for that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

风筝在阴天搁浅。 2024-11-11 22:50:26

这适用于 g++ 4.5.1:

class X {
   ...


    friend auto operator+( const X & a, const X & b )->decltype( X::value_ + X::value_  );
};

auto operator+( const X & a, const X & b )->decltype( X::value_ + X::value_) {
    return a.value_ + b.value_;
}

This works with g++ 4.5.1:

class X {
   ...


    friend auto operator+( const X & a, const X & b )->decltype( X::value_ + X::value_  );
};

auto operator+( const X & a, const X & b )->decltype( X::value_ + X::value_) {
    return a.value_ + b.value_;
}
久光 2024-11-11 22:50:26

它看起来像是一个编译器错误,而不是任何故意的(哪个编译器?考虑提交一个错误)。但是,您始终可以执行 带有函数的 auto 规范(当然避免这是新语法的动机,但如果它不起作用......),即:

decltype((*(X*)0).value_ + (*(X*)0).value_)

两边都有相同的 X ,因此您可以在 X 中创建 typedef,这样您就不必在运算符的声明和定义中键入这种令人讨厌的内容。

(编辑)对于两侧没有相同 X 的情况,您仍然可以通过使用 decltype 准备模板(特征)并使用它来声明运算符来分解声明,这样就不会太可怕了。像这样的东西:

template <typename X, typename Y>
struct PlusType {
    typedef decltype((*(X*)0).value_ + (*(Y*)0).value_) Type;
}

template <typename X, typename Y>
PlusType<X, Y>::Type operator+(X &x, Y &y);

It looks like a compiler bug rather than anything intentional (which compiler? consider filing a bug). However, you can always do the ugly alternative described in the specification for auto with functions (of course avoiding that is motivation for the new syntax, but if it does not work...), namely:

decltype((*(X*)0).value_ + (*(X*)0).value_)

You have the same X on both sides, so you can make a typedef in X so you don't have to type out this obnoxiousness both in declaration and definition of the operator.

(Edit) For cases where you don't have the same X on both sides, you can still factor the declaration so that it's not too horrible by preparing a template (trait) with the decltype and using it to declare the operator. Something like:

template <typename X, typename Y>
struct PlusType {
    typedef decltype((*(X*)0).value_ + (*(Y*)0).value_) Type;
}

template <typename X, typename Y>
PlusType<X, Y>::Type operator+(X &x, Y &y);
明天过后 2024-11-11 22:50:26

在我看来,在你的情况下,使用 auto 没有多大意义,你最好说操作符返回 int。

这里的问题是,为了能够编写 rhs.value_ rhs 必须是完整类型的实例。在类结束 } 后,类型 X 被认为是完整的。所以编译器有理由抱怨。

EDIT3:

因为在我看来,我的上述解释并不完整,可能会导致混乱。

struct X
{

   //code ommited for brevity...
   //at this line one has decltype(lhs.value_ + rhs.value_) where 
   //lhs and rhs are of type X however the X type is not yet complete. 
   //The compiler has to however determine the type of the friend including 
   //the return type...
   friend auto operator+(const X& lhs, const X& rhs)-> decltype(lhs.value_ + rhs.value_);
};

编辑:

有关 VS2010 与 decltype 相关的讨论,解释了为什么它在 VS2010 中是这样的,还解释了为什么它是标准兼容的,你可以查看 此处

我的第一个选择是删除 auto。但是,假设您提供了一个更简单的示例来进行说明,并且在您的实际情况下 auto 实际上是有意义的,您可以尝试:

struct X
{
private:
    int value_;
public:
    X() : value_(int()) { }

    X(int value):value_(value) { }

    template <typename T>
    auto operator+(const T& rhs) -> decltype(value_ + rhs.value_)
    {
        return value_ + rhs.value_;
    }
};

int main(int argc, char* argv[])
{
    X a(5);
    X b(6);
    std::cout << a + b;

    return 0;
}

EDIT2:

为了完整性(并说明这不是 auto 和朋友的问题,而是尝试使用不完整的问题)类型考虑以下代码(这也实现了你想要的,但以一种扭曲的不推荐的方式:-)):

#include <iostream>

struct X
{
public:
        X() : value_(int())     { }

        X(int value):value_(value) { }

        int value_;

};

struct A : public X
{
        friend auto operator+(const X& lhs, const X& rhs) -> decltype(lhs.value_ + rhs.value_);
};

auto operator+(const X& lhs, const X& rhs) -> decltype(lhs.value_ + rhs.value_)
{
        return lhs.value_ + rhs.value_;
}

int main(int argc, char* argv[])
{
        X a(5);
        X b(6);
        std::cout << a + b;

        return 0;
}

代码在VS2010和gcc-4.5.1中编译正常

In my opinion, in your situation, using auto does not make all that much sense, you would be probably better off saying the operator returns int.

The issue here is that in order to be able to write rhs.value_ rhs must be an instance of a complete type. The type X is considered complete after the closing } of the class. So the compiler is rightfully complaining.

EDIT3:

Since it seems to me my above explanation was not complete and could lead to confusion.

struct X
{

   //code ommited for brevity...
   //at this line one has decltype(lhs.value_ + rhs.value_) where 
   //lhs and rhs are of type X however the X type is not yet complete. 
   //The compiler has to however determine the type of the friend including 
   //the return type...
   friend auto operator+(const X& lhs, const X& rhs)-> decltype(lhs.value_ + rhs.value_);
};

EDIT:

For a discussion on VS2010 relating to decltype that explains why it is the way it is in VS2010 and also explains why it is standard compilant how it is in VS2010 you can look here:

My first option would be to drop auto. However, assuming you have provided a simpler example for illustration, and in your real case auto would actually make sense you could try:

struct X
{
private:
    int value_;
public:
    X() : value_(int()) { }

    X(int value):value_(value) { }

    template <typename T>
    auto operator+(const T& rhs) -> decltype(value_ + rhs.value_)
    {
        return value_ + rhs.value_;
    }
};

int main(int argc, char* argv[])
{
    X a(5);
    X b(6);
    std::cout << a + b;

    return 0;
}

EDIT2:

For completness (and to illustrate this is not an issue with auto and friend but rather attempting to use an incomplete type consider the following code (that also achieves what you want but in a twisted not recommendable way :-) ):

#include <iostream>

struct X
{
public:
        X() : value_(int())     { }

        X(int value):value_(value) { }

        int value_;

};

struct A : public X
{
        friend auto operator+(const X& lhs, const X& rhs) -> decltype(lhs.value_ + rhs.value_);
};

auto operator+(const X& lhs, const X& rhs) -> decltype(lhs.value_ + rhs.value_)
{
        return lhs.value_ + rhs.value_;
}

int main(int argc, char* argv[])
{
        X a(5);
        X b(6);
        std::cout << a + b;

        return 0;
}

The code compiles ok in VS2010 and gcc-4.5.1

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文