why i can't use array of references

Jan 28, 2010 at 10:49am
hi, yesterday i read about arrays, and surprised when i read that C++ doesn't support array of references. my main question is why, is there any reasons?
Jan 28, 2010 at 12:28pm
Because references aren't considered objects by the language, unlike integers, pointers, etc. You also can't have pointers to references and you can't dynamically allocate references. There are only two valid uses of references:
1
2
3
T &r=/*...*/;

T f(/*...*/T2 &p/*...*/){/*...*/}

All these restrictions come from the fact that the language doesn't allow uninitialized references.

EDIT: Oh, they can also be class members, but they have to be initialized in an initialization list in the constructor, and having at least one reference as a class member makes the class uncopyable.
Last edited on Jan 28, 2010 at 12:55pm
Jan 29, 2010 at 9:42am
...and having at least one reference as a class member makes the class uncopyable
That almost sounds like a challenge.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>

template <typename T>
class Ref
{
public:
    Ref(T &val) : ref(val) { }
    Ref(const Ref &other) : ref(other.ref) { }
    Ref & operator=(const Ref &other)
    {
        if (&other != this)
        {
            this->Ref::~Ref();      // Evil
            new (this) Ref(other);  // Evil
        }
        return *this;
    }
    Ref & operator=(const T &val)
    {
        ref = val;
        return *this;
    }
    operator T() const
    {
        return ref;
    }
private:
    T &ref;
};

int main(int argc, char *argv[])
{
    // Initialise a reference
    int i(10);
    Ref<int> ref1(i);
    std::cout << ref1 << std::endl;

    // Change i by reference
    ref1 = 13;
    std::cout << i << std::endl;

    // Copy to int by value
    int k(ref1);
    std::cout << k << std::endl;

    // "Copy" a reference :P
    Ref<int> ref2(ref1);
    std::cout << ref2 << std::endl;
    i = 12;
    std::cout << ref1 << std::endl;
    std::cout << ref2 << std::endl;

    // "Reassign" a reference :P
    int j(5);
    Ref<int> ref3(j);
    std::cout << ref3 << std::endl;
    ref3 = ref1;
    std::cout << ref3 << std::endl;

    return 0;
}

which produces

10
13
13
13
12
12
5
12



Edit: Added conversion operator.
Last edited on Jan 29, 2010 at 10:21am
Jan 29, 2010 at 10:44am
@SCSI 73rm1n8r
wow, that is indeed evil !!!
Jan 29, 2010 at 12:43pm
Not as evil as this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    int a1(0), a2(1), a3(2), a4(3);

    // Not too evil
    Ref<int> staticRefArray[] = {a1, a2, a3, a4};
    std::cout << staticRefArray[0] << " "
              << staticRefArray[1] << " "
              << staticRefArray[2] << " "
              << staticRefArray[3] << std::endl;

    // Now with an STL container
    std::vector<Ref<int> > vectorRef;
    vectorRef.push_back(a1);
    vectorRef.push_back(a2);
    vectorRef.push_back(a3);
    vectorRef.push_back(a4);
    std::cout << vectorRef[0] << " "
              << vectorRef[1] << " "
              << vectorRef[2] << " "
              << vectorRef[3] << std::endl;

    // Now the hard way (circumventing the default constructor requirement for dynamic arrays)
    Ref<int> *dynamicRefArray = static_cast<Ref<int>*>(::operator new (sizeof(Ref<int>)*4));
    new (&dynamicRefArray[0]) Ref<int>(a1);
    new (&dynamicRefArray[1]) Ref<int>(a2);
    new (&dynamicRefArray[2]) Ref<int>(a3);
    new (&dynamicRefArray[3]) Ref<int>(a4);
    std::cout << dynamicRefArray[0] << " "
              << dynamicRefArray[1] << " "
              << dynamicRefArray[2] << " "
              << dynamicRefArray[3] << std::endl;
    dynamicRefArray[0].~Ref();
    dynamicRefArray[1].~Ref();
    dynamicRefArray[2].~Ref();
    dynamicRefArray[3].~Ref();
    ::operator delete (dynamicRefArray);
Jan 29, 2010 at 12:59pm
It all screams "abuse" to me, anyway.
Topic archived. No new replies allowed.