有时当我用C ++编程时,我希望每个变量都有一个undefined
值,就像Javascript!
例如,当我为数组的out-of-bounds元素返回一个值时,返回undefined
而不是抛出异常很有用,或者:
template <typename T, int SIZE>
class MyArray
{
T arr[SIZE];
static T badref;
public:
T &operator[](int i)
{
if (i >=0 && i < SIZE)
return arr[i];
else
throw std::string("OUT-OF-BOUNDS"); // or: return badref; !!
}
};
另一个脏(在我看来)选项是将预定义变量的引用作为坏引用变量返回。我知道我们不能将null
或类似的内容分配给引用变量。
是否有另一个格式良好的模式返回一个引用,其中调用者能够找出返回的值无效?
编辑:我不是指pointer
答案 0 :(得分:5)
你可以在评论中提到使用boost :: optional作为@chris。它是Boost libary的一部分。有关详细信息,请参阅this page。
修改后的MyArray
类:
template <typename T, int SIZE>
class MyArray
{
T arr[SIZE];
public:
optional<T&> operator[](int i)
{
if (i >=0 && i < SIZE)
return optional<T&>(arr[i]);
else
return optional<T&>();
}
};
用法:
MyArray<int>() array;
// fill array with data
optional<int&> result = array[0];
if (result) {
// item was found
} else {
// index out of bounds
}
答案 1 :(得分:3)
我希望每个变量都有一个未定义的值,比如Javascript!
指针只有一个“未定义”值(nullptr)。引用是(根据定义)指向有效实例的东西。
要返回对静态对象的引用,您应该将运算符的const和非const值分开:
template <typename T, int SIZE>
class MyArray
{
T arr[SIZE];
static T badref;
public:
T &operator[](int i)
{
if (i >=0 && i < SIZE)
return arr[i];
else
// returning ref here would allow clients to write:
// MyArray<int> a;
// a[-1] = 5; // valid if you return a non-const reference
throw std::string("OUT-OF-BOUNDS");
}
const T &operator[](int i) const
{
if (i >=0 && i < SIZE)
return arr[i];
else {
// MyArray<int> a;
// a[-1] = 5; // will not compile (cannot assign to const)
static const T invalid = T();
return invalid;
}
}
};
答案 2 :(得分:2)
无论您如何看待,您的解决方案都需要适应类型系统。所以你的函数签名必须明确地说(这样或那样)结果可能是T,但也可能是其他东西。
常见的方法是:
不是返回值,而是返回状态代码并通过“out”参数(指针或引用)输出值:
bool tryGet(int i, T& result);
返回一个元组(状态,值),如:
std::tuple<bool, T> get(int i)
(如果无法获取,请考虑第二个元组元素无关 - 要求T具有默认构造函数)
使用boost::variant
(灵活,但需要提升)
boost::optional
(上述更简单的版本,当您只需要“T或无”时)答案 3 :(得分:0)
引用的主要目标是避免无效(NULL)值,同时允许函数修改其参数并防止复制数据。如果需要NULL值,请使用指针。