开发者

How may I forbid calls to const member function of an rvalue object in C++ 2011?

The following code

#include <vector>
#include <string>
#include <iostream>

std::string const& at(std::vector<std::string> const& n, int i)
{
    return n[i];
}

std::vector<std::string> mkvec()
{
    std::vector<std::string> n;
    n.push_back("kagami");
    n.push_back("misao");
    return n;
}

int main()
{
    std::s开发者_如何学Gotring const& s = at(mkvec(), 0);
    std::cout << s << std::endl; // D'oh!
    return 0;
}

may lead to crash because the original vector is already destructed there. In C++ 2011 (c++0x) after rvalue-reference is introduced in, a deleted function declaration can be used to completely forbid calls to at if the vector argument is an rvalue

std::string const& at(std::vector<std::string>&&, int) = delete;

That looks good, but the following code still cause crash

int main()
{
    std::string const& s = mkvec()[0];
    std::cout << s << std::endl; // D'oh!
    return 0;
}

because calls to member function operator [] (size_type) const of an rvalue object is still allowed. Is there any way can I forbid this kind of calls?

FIX:

The examples above is not what I did in real projects. I just wonder if C++ 2011 support any member function qualifying like

class A {
    void func() rvalue; // Then a call on an rvalue object goes to this overload
    void func() const;
};

FIX:

It's great, but I think C++ standard goes too far at this feature. Anyway, I have following code compiled on clang++ 2.9

#include <cstdio>

struct A {
    A() {}

    void func() &
    {
        puts("a");
    }

    void func() &&
    {
        puts("b");
    }

    void func() const &
    {
        puts("c");
    }
};

int main()
{
    A().func();
    A a;
    a.func();
    A const b;
    b.func();
    return 0;
}

Thanks a lot!


No, and you shouldn't. How am I to do std::cout << at(mkvec(), 0) << std::endl;, a perfectly reasonable thing, if you've banned me from using at() on temporaries?

Storing references to temporaries is just a problem C++ programmers have to deal with, unfortunately.


To answer your new question, yes, you can do this:

class A {
    void func() &; // lvalues go to this one
    void func() &&; // rvalues go to this one
};

A a;
a.func(); // first overload

A().func(); // second overload


Just an idea:

To disable copying constructor on the vector somehow.

vector ( const vector<T,Allocator>& x );

Implicit copying of arrays is not that good thing anyway. (wondering why STL authors decided to define such ctor at all)

It will fix problems like you've mentioned and as a bonus will force you to use more effective version of your function:

void mkvec(std::vector<std::string>& n)
{
    n.push_back("kagami");
    n.push_back("misao");
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜