Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

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).

like image 518
mecahi Avatar asked Apr 13 '26 02:04

mecahi


2 Answers

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.

like image 150
Drax Avatar answered Apr 15 '26 14:04

Drax


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");
};
like image 40
Angew is no longer proud of SO Avatar answered Apr 15 '26 14:04

Angew is no longer proud of SO



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!