2

我想知道当参数不满足if条件时这个get函数应该返回什么

    template <class Object>
    const Object& SparseMat<Object>::get(int c, int r) //const
    {
        if((c >= 0)&&(c <= cCapacity)&&(r >= 0)&&(r <= rCapacity))
        {
            return mObjects[c][r];
        }
        //what should I return here?
    }
4

3 回答 3

11

你应该抛出一个异常:

#include <stdexcept>

throw std::out_of_range("Indexes are out of range");
于 2013-10-09T17:47:09.430 回答
4

您实际上有多种选择,特别是如果您愿意更改签名。

最有可能的是,您想发出错误信号,这里的异常非常有趣:

template <class Object>
const Object& SparseMat<Object>::get(int c, int r) const
{
    if((c >= 0)&&(c <= cCapacity)&&(r >= 0)&&(r <= rCapacity))
    {
        return mObjects[c][r];
    }
    throw UnknownCoordinates(c, r, cCapacity, rCapacity);
}

或者,更改签名,您可以包含无效性的概念:

template <class Object>
Object const* SparseMat<Object>::get(int c, int r) const
{
    if((c >= 0)&&(c <= cCapacity)&&(r >= 0)&&(r <= rCapacity))
    {
        return &mObjects[c][r];
    }
    return nullptr;
}

可以使用以下方法更明确boost::optional

template <class Object>
boost::optional<Object const&> SparseMat<Object>::get(int c, int r) const
{
    if((c >= 0)&&(c <= cCapacity)&&(r >= 0)&&(r <= rCapacity))
    {
        return mObjects[c][r];
    }
    return boost::none;
}

或者,在不更改签名的情况下,您可能希望使用空对象,但这几乎不是最佳选择(它将您限制为嵌入空概念的对象,并且此类对象最好重构为不具有空概念,而是依靠boost::optional<Object>

template <class Object>
const Object& SparseMat<Object>::get(int c, int r) const
{
    if((c >= 0)&&(c <= cCapacity)&&(r >= 0)&&(r <= rCapacity))
    {
        return mObjects[c][r];
    }
    return null; // where null is "static Object const null;" for example.
}
于 2013-10-09T17:54:18.390 回答
0

完全由您决定它应该返回什么以及是否应该返回。也许而不是返回它应该中止(“崩溃”)或抛出异常?正如其他答案已经建议的那样,在这种情况下,抛出异常可能是嵌套方法。

但是,如果您确实坚持要返回某些内容以响应错误输入,那么在这种情况下,您可以选择一个预定义的“虚拟”/“监护人”类型的对象,Object该对象专门用于处理此类情况。

template <class Object>
class SparseMat 
{
  ...
  static Object error_object;
};


template <class Object>
const Object& SparseMat<Object>::get(int c, int r) //const
{
    if((c >= 0)&&(c <= cCapacity)&&(r >= 0)&&(r <= rCapacity))
    {
        return mObjects[c][r];
    }

    return error_object;
}

根据设计,您可能希望error_object通过调用代码轻松识别它。或者你可以设计那个“监护人”对象,这样调用代码就可以正常工作,甚至没有意识到返回的对象是一个“虚拟”。同样,这由您决定。

于 2013-10-09T18:25:07.683 回答