hide vector implementation

Hi

I am attempting to hide the fact that a class is using a vector to hold the data. I need to do so without creating a proxy class, which I have seen is straightforward.

The working class declaration is:
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
#ifndef _TESTER1_H_
#define _TESTER1_H_

#include <memory>
#include <iostream>
#include <vector>

template <typename T>
class tester {
  private:
    const std::vector<T> vd;
    mutable std::unique_ptr<T> balance;
    T calc_balance() const;
    void print(std::ostream & os) const;
    
  public:
    explicit tester<T>(const std::vector<T> & test_balance ) : vd{ test_balance }, balance(nullptr) { }
    tester<T>() = default;
    ~tester<T>() = default;

    T get_balance() const;

    template <typename Y>
    friend std::ostream & operator<<(std::ostream & os, const tester<Y> & tst);
};

#include "tester1.cpp"
#endif 

I would like to modify it to something as follows:
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
#ifndef _TESTER1_H_
#define _TESTER1_H_

#include <memory>
#include <iostream>
#include <vector>

template <typename T>
class tester {
  private:
    const std::vector<T> vd;
    using sample_container_type = std::vector<T>;
    using sample_container = sample_container_type<T>;

    mutable std::unique_ptr<T> balance;
    T calc_balance() const;
    void print(std::ostream & os) const;
    
  public:
    explicit tester<T>(const std::vector<T> & test_balance ) : vd{ test_balance }, balance(nullptr) { }
    tester<T>() = default;
    ~tester<T>() = default;

    using iterator = sample_container<T>::iterator;
     using const_iterator = sample_container<T>::const_iterator;
    T get_balance() const;
    

    template <typename Y>
    friend std::ostream & operator<<(std::ostream & os, const tester<Y> & tst);
};

#include "tester1.cpp"
#endif 


I get the following compile error for the 2nd listing:
1
2
3
4
5
6
7
8
9
c++ -g -std=c++14 -pedantic -Wall -Wpointer-arith -Wwrite-strings -Wcast-qual -Wcast-align -Wformat-security -Wformat-nonliteral -Wmissing-format-attribute -Winline -funsigned-char "main.cpp" (in directory: /c++/tester)
In file included from main.cpp:3:0:
tester1.h:13:30: error: ‘tester<T>::sample_container_type’ is not a template
     using sample_container = sample_container_type<T>;
                              ^
tester1.h:24:22: error: ‘tester<T>::sample_container’ is not a template
     using iterator = sample_container<T>::iterator;
                      ^
Compilation failed.


Any ideas on how I can hide the vector without getting the above errors?
Last edited on
> ‘tester<T>::sample_container_type’ is not a template
note where is T.
If you do tester<int>::sample_container_type foo then `foo' would be of type std::vector<int>
same for `sample_container', they are not templates.

So you may do using iterator = typename sample_container::iterator;


¿why do you need `sample_container' and `sample_container_type'?
Last edited on

Hi ne555

thanks for replying. I've modified the code to take your suggestion into account. The question remains though on how I can make sample_container known publicly without showing that it is of type vector.

Modified code:
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
#ifndef _TESTER1_H_
#define _TESTER1_H_

#include <memory>
#include <iostream>
#include <vector>
#include <initializer_list>

template <typename T>
class tester {
  private:
    using sample_container = std::vector<T>;
    sample_container sample_items;
    
    mutable std::unique_ptr<T> balance;
    T calc_balance() const;
    void print(std::ostream & os) const;
    
  public:
    using sample_container; // public interface. LINE GENERATES ERROR!!

    // users should be able to pass data in in 1 of 3 ways
    // but the fact that vector appears as 1 of the ways does
    // not expose the implementation details of the private vector
    explicit tester<T>(const std::initializer_list<T> & test_balance ) :
      sample_items{ test_balance }, balance(nullptr) { }

    explicit tester<T>(const sample_container & test_balance ) :
      sample_items{ test_balance }, balance(nullptr) { }

    tester<T>() = default;
    ~tester<T>() = default;
    tester<T>(const tester<T> & bal) { }; // copy constructor

    typedef typename  sample_container::iterator iterator;
    typedef typename  sample_container::const_iterator const_iterator;

    iterator begin() {return sample_items.begin();}
    const_iterator begin() const {return sample_items.begin();}
    const_iterator cbegin() const {return sample_items.cbegin();}
    iterator end() {return sample_items.end();}
    const_iterator end() const {return sample_items.end();}
    const_iterator cend() const {return sample_items.cend();}

    T get_balance() const;
    T get_avg() const;
    const sample_container & get_data() const { return sample_items; }

    template <typename Y>
    friend std::ostream & operator<<(std::ostream & os, const tester<Y> & tst);
};

#include "tester1.cpp"
#endif 

compile error generated is:
1
2
3
4
5
6
c++ -g -std=c++14 -pedantic -Wall -Wpointer-arith -Wwrite-strings -Wcast-qual -Wcast-align -Wformat-security -Wformat-nonliteral -Wmissing-format-attribute -Winline -funsigned-char "main.cpp" (in directory: /c++/tester)
In file included from main.cpp:3:0:
tester1.h:20:11: error: expected nested-name-specifier before ‘sample_container’
     using sample_container; // public interface. LINE GENERATES ERROR!!
           ^
Compilation failed.
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
template<class T>
class tester{
public:
	using simple_container = std::vector<T>; //¿you don't like this?

private:
	simple_container sample_items;
	//...
public:
	//...
};

template<class T>
class tester{
private:
	using simple_container_type = std::vector<T>; //¿do you think this is hidden?
public:
	using simple_container = simple_container_type;

private:
	simple_container sample_items;
	//...
public:
	//...
};

OP: I think you might be looking for the pointer-to-implementation (Pimpl) idiom:
https://herbsutter.com/gotw/_100/
http://stackoverflow.com/questions/206272/hiding-private-data-members-c
Topic archived. No new replies allowed.