2012-11-16 69 views
8

有时,当我用C++编程时,我希望每个变量都有一个undefined的值,比如Javascript !. 例如,当我再次回到了阵外的界限元素的值,它是有用的返回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

+5

是的,它被称为指针。或者,'boost :: optional'。 – chris

+2

至少让你的badref对象静态,那么它不会占用你创建的每个MyArray的空间。但我同意,这很丑陋。在这样的泛型代码中,我宁愿抛出异常 – john

+0

@john:是的,我编辑了它。 – deepmax

回答

5

您可以使用boost ::可选的,因为在他的评论中提到@克里斯。它是作为Boost库的一部分。有关更多详细信息,请参阅this page

修改类:

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 
} 
+0

badref是什么? –

+0

@DenisErmolin我个人更喜欢boost :: optional,因为它明确指出operator []的返回值可能是未定义的,您应该检查这个条件。 –

+0

@MasoudM。我编辑了我的答案并添加了文档链接。你可以在这里找到更多关于Boost的信息:http://www.boost.org/doc/libs/1_52_0/index.html –

2

不管你认为,你的解决方案需要适合的类型系统。所以你的函数签名必须明确地说(这种或那种)结果可能是T,但它可能是其他的东西。对于

常见方法是:

bool tryGet(int i, T& result); 

  • 而不是返回值的,通过一个“去”参数(的指针或引用)返回一个状态码和输出的值

  • 返回的元组(状态,值),如:

    std::tuple<bool, T> get(int i) 
    

    (如果。 ouldn't得到,考虑第二元组元素无关 - 需要吨至有一个默认的构造函数)

  • 使用boost::variant(灵活,但需要提升)

  • 使用boost::optional(上述的简单版本,当你只需要“T或无”)
3

我希望有一个像Javascript这样的每个变量都有一个未定义的值!

您只有指针(nullptr)的“未定义”值。参考(根据定义)指向有效的实例。

要返回引用静态对象,你应该将运营商的常量和非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; 
    } 
    } 

};

0

引用的主要目标是避免无效(NULL)值,同时允许函数修改它们的参数并避免复制数据。如果您需要NULL值,请使用指针。