0

I know, I've posted 3 times already today, but this one is actually valid.

I have 3 classes

operation.hpp

#include <iostream>

using namespace std;

template<typename t>
class Operation {
    public:
        bool computed;
        int type;
        int apply_type;
        t result;

        Operation(int type, int apply_type) {
            computed = false;
            this->type = type;
            this->apply_type = apply_type;
        }

        Operation(const Operation& op) {
            computed = op.computed;
            type = op.type;
            apply_type = op.apply_type;
        }

        virtual ostream& out(ostream& stream) const {
            return stream << "Operation { type: " << type << "[" << apply_type << "], computed: " << computed << " }" << endl;
        }

        virtual void compute_op() { computed = true; }

        virtual t compute() {
            if(!computed) compute_op();
            return result;
        }
};

template<typename t>
inline std::ostream& operator<<(std::ostream& stream, const Operation<t>& op) { return op.out(stream); }

template<typename t>
class UnaryOperation : public Operation<t> {
    private:
        UnaryOperation() {};
    public:

        bool arg1;

        UnaryOperation(bool arg1, int type, int apply_type) : Operation<t>(type, apply_type) {
            this->arg1 = arg1;
        }

        UnaryOperation(const UnaryOperation& op) : Operation<t>(op) {
            arg1 = op.arg1;
        }

        virtual ostream& out(ostream& stream) const {
            return stream << "Operation { type: " << type << "[" << apply_type << "], computed: " << computed << ", arg1: " << arg1 << " }" << endl;
        }

        void compute_op(bool arg1) { Operation<t>::compute_op(); }
};

class UnaryApplyOperation : public UnaryOperation<bool> {
    public:
        UnaryApplyOperation(bool arg1, int type, int apply_type) : UnaryOperation<bool>(arg1, type, apply_type) {}
        UnaryApplyOperation(const UnaryApplyOperation& op) : UnaryOperation<bool>(op) {}

        void compute_op(bool arg1) { 
            UnaryOperation<bool>::compute_op(arg1);
            result = arg1; 
        }
};

class NotOperation : public UnaryApplyOperation {
    public:
        NotOperation(bool arg1) : UnaryApplyOperation(arg1, 0, 0) {}
        NotOperation(const NotOperation& op) : UnaryApplyOperation(op) {}

        void compute_op(bool arg1) { 
            UnaryApplyOperation::compute_op(arg1);
            result = !arg1; 
        }
};

When I try to compile this, I get the following error:

so_c++_template_inheritance_question.cpp: In member function ‘virtual std::ostream& UnaryOperation<t>::out(std::ostream&) const’:
so_c++_template_inheritance_question.cpp:57:54: error: ‘type’ was not declared in this scope; did you mean ‘wctype’?
   57 |             return stream << "Operation { type: " << type << "[" << apply_type << "], computed: " << computed << ", arg1: " << arg1 << " }" << endl;
      |                                                      ^~~~
      |                                                      wctype
so_c++_template_inheritance_question.cpp:57:69: error: ‘apply_type’ was not declared in this scope
   57 |             return stream << "Operation { type: " << type << "[" << apply_type << "], computed: " << computed << ", arg1: " << arg1 << " }" << endl;
      |                                                                     ^~~~~~~~~~
so_c++_template_inheritance_question.cpp:57:102: error: ‘computed’ was not declared in this scope; did you mean ‘compute_op’?
   57 |             return stream << "Operation { type: " << type << "[" << apply_type << "], computed: " << computed << ", arg1: " << arg1 << " }" << endl;
      |                                                                                                      ^~~~~~~~
      |

I found a way to workaround this, by using this->type and this->apply_type and this->computed, but I'm still curious, why I get the error when obviously the variables are already defined, and inherited in?

iggy12345
  • 1,233
  • 12
  • 31
  • 1
    It has already been answered [here](https://stackoverflow.com/questions/1120833/derived-template-class-access-to-base-class-member-data) You may find explanation [here](https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-members) – Vladimir Nikitin May 15 '20 at 14:43
  • @VladimirNikitin That was helpful, but is there an explanation, as to why that is required? Why do you have to use `this` and or the namespace/class-name? – iggy12345 May 15 '20 at 15:13
  • @VladimirNikitin I'm not sure if my @ in the last comment worked – iggy12345 May 15 '20 at 15:21
  • [here](https://stackoverflow.com/questions/4643074/why-do-i-have-to-access-template-base-class-members-through-the-this-pointer) is explanation i suppose you're looking for. – Vladimir Nikitin May 15 '20 at 15:53

0 Answers0