简体   繁体   中英

Returning reference to private members inside a template class

I have the following code.

#include <iostream>
#include <vector>

template <typename T> class testTemp {
    std::vector<T> container;
public:
    std::vector<T&> getTest(int nrOfEle);
    void push(T row){container.push_back(row);}
};

template<typename T>
std::vector<T&> testTemp<T>::getTest(int nrOfEle) {
    std::vector<T&> refContainer;
    for(int i =0; i < nrOfEle; i++){
        refContainer.push_back(container[i]);
    }
    return refContainer;
}


int main() {
    testTemp<std::vector<int> > test; // T =std::vector<std::int>
    std::vector<int> fillMeUp;
    for(int i=0; i < 10; i++){
        fillMeUp.push_back(i);
    }

    test.push(fillMeUp);
    std::vector<int> container = test.getTest(3); // when i change the elements in container
    container[0] = 999; //this change should also affect the private `member inside the testTemp class`

    return 0;
}

What I want to be able to do, is from main call the function getTest() with the number of elements I want to change. In the code above I want to change the 3 first elements. So I input that into the function. The function should then return a container to main containing the 3 first elements of the private member std::vector container as references so that when i make a change in main it also changes the element in the class container std::vector container. I'm not quite sure how to achieve this. The code above is my first attempt but it results in an error

 "/usr/include/c++/9/ext/new_allocator.h:63:26: error: forming pointer
 to reference type ‘std::vector<int>&’    63 |       typedef _Tp*      
 pointer;"

after reading the comment by formerlyknownas_463035818 i've changed to

   template<typename T>
      T* testTemp<T>::getTest(int nrOfEle) {

      return &container[nrOfEle];
      }

however this seems to return the address of the vector object rather than the element

You cannot have a std::vector of references. There is std::reference_wrapper , but I would suggest a different design. Instead of returning a new vector, I would rather return a begin and end (3rd element) iterator. Those iterators can be coming directly from the private member. If you are worried about the caller modifiying elements beyond the 3rd you could write a wrapper for the iterator that only provides access to the first three elements.

Something along the line of:

template <typename T> class testTemp {
    std::vector<T> container;
public:
    std::vector<T>::iterator getTest_begin() { return container.begin(); }
    std::vector<T>::iterator getTetst_end(int nrOfEle) { return container.begin() + nrOfEle; }
    void push(T row){container.push_back(row);}
};

Of course you should make sure that the container actually does contain enough elements.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM