Justin
Justin

Reputation: 51

inheritance of private member variable from class template

I made a class template looks like below, as base class for other classes to inherit from, and it would work fine as expected.

But my question is, The code still compiles even if I change 'protected' of class 'Operation' to 'private', even Matmul(which inherits class 'Operation') is modifying vector called 'edgeIn' which is declared as 'private'.

I can't understand why something like this should be allowed... Shouldn't compiler trigger error message on this? (derived class shouldn't modify private member of base class)

template<typename T>
class Operation{
private: //Would compile fine even if I change this to 'private!'
    class edge{
    public:
        edge(Tensor<T> tensor, Operation<T> &from, Operation<T> &to) {
            this->tensor = tensor;
            this->from = from;
            this->to = to;
        }
        Operation<T> from;
        Operation<T> to;
        Tensor<T> tensor;
    };
    std::vector<edge> edgeIn; //edges as inputs of this operation
    std::vector<edge> edgeOut; //edges as outputs of this operation
private:
    //disable copy constructor (NOT ALLOWED)
    Operation(Operation<T>& rhs) = default;
    //disable move operator (NOT ALLOWED)
    Operation<T>& operator=(Operation<T> &rhs) = default;
    int operationId;
};

template<typename T>
class Matmul: public Operation<T>{
public:
    Matmul(std::initializer_list<std::pair<Tensor<T>, Operation<T>>> args);
};

template<typename T>
//from Operation<T>, to This operation
Matmul<T>::Matmul(std::initializer_list<std::pair<Tensor<T>, Operation<T>>> args){
    for(auto elem: args){
        typename Operation<T>::edge info{elem.first, elem.second, *this};
        this->edgeIn.emplace_back(info); //modifying member of base class
    }
}

Upvotes: 0

Views: 134

Answers (1)

Pete Becker
Pete Becker

Reputation: 76305

In the code you've shown, it's allowed because it's not wrong. Here's a simpler example:

template <class Ty>
class base {
    int i; // private
};

template <class Ty>
class derived : base {
    void set(int ii) { i = ii; }
};

At this point, if you write

derived<int> di;
di.set(3); // illegal: i is not accessible

you'll get an access error, as you expect.

But the original template isn't wrong, because the code might do this:

template <>
class base<int> {
public:
    int i;
};

Now you can write

derived<int> di;
di.set(3);

and it's okay, because i is public in base<int>. You still can't write

derived<double> dd;
dd.set(3); // illegal: i is not accessible

Upvotes: 1

Related Questions