简体   繁体   中英

C++, What to return from a function with reference return type to indicate error

Imagine that we have a class

class cFoo {};

and another one with a vector of cFoo object, like this:

class cContainer
    {
        public:
            const cFoo& getFoo(std::size_t index) const;
        private:
            std::vector<cFoo> fooList_;
    }
    const fCoo& cContainer::getfoo(std::size_t index) const
    {
        if(index < fooList_.size())
            return fooList_[index];
        else
            ??????????
    };

So my question is "What is the best practice in this case?". That is what to put after the else part in place of ????s. This question is valid for any member function returning a reference (be it const or not). When we don't have anything to return, what should be returning?

Obviously returning a local temporary variable is out of question. Another solution comes to my mind is to return a static instance of cFoo() most possibly defined and initialized during cFoo class definition/implementation.

Of course we can abstain from returning references in this cases but it might be poor choice performance wise (especially if we lack the goodies like move operator).

What the STL does in this case is throw an exception.

For exemple you can take a look at the std::vector::at member function:

http://en.cppreference.com/w/cpp/container/vector/at

which throws an std::out_of_range exception if you ask for something out of range


Another option is to return either a pointer or its more semanticaly explicit equivalent in this context, an optional reference boost::optional<fCoo&> .

I would advise to go this way if the "out of range" case is not that exceptional and is supposed to happen from time to time.

Lastly if you consider that this case should never happen except if it is a developper error, you should use an assertion .

If not having something to return is normal for the function, it shouldn't be returning a reference. There's nothing wrong with returning a pointer:

const fCoo* cContainer::getfoo(std::size_t index) const
{
    if(index < fooList_.size())
        return fooList_[index];
    else
        return nullptr;
};

If not having anything to return is indicates something exceptional for the function, well then, it should throw an exception:

const fCoo* cContainer::getfoo(std::size_t index) const
{
    if(index < fooList_.size())
        return fooList_[index];
    else
        throw std::invalid_argument("out of range");
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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