Search code examples
c++templatesvariadic-templates

How to make base class's operators visible with variadic number of base classes (please see code below)?


What is the best way to expose operators from base class like the following code is trying to do. I suppose with one or two base classes we'd use using syntax, but with a variadic number of base classes, is something like using Base<Ts>::operator=...; possible?

template <typename T, typename Derived>
class varU
{
    protected:
    varU() = default;

    Derived& operator=(T val)
    {
        static_cast<Derived*>(this)->set(val);
        return *static_cast<Derived*>(this);
    }
};

template <typename ...Ts>
class var : public varU<Ts, var<Ts...>>...
{
    // using varU<Ts, var<Ts...>>::operator=...;  // Something like this?

    private:
    template <typename T>
    void set(const T& v)
    {
    }
};

EDIT:

Seems like using Base<Ts>::operator=... is indeed the correct syntax which I was looking for in C++17. I was using the wrong standard version and expecting C++17. Since this was my guess, I didn't dig deep.


Solution

  • I'm not exactly sure, what you want to achieve with your code, so perhaps you want to go a bit more into detail in your question.

    But regarding your question in the code-comment, the answer is yes, it's possible in C++17. If you actually want to use your operators, you also have to declare the varU class a friend of var:

    The following compiles on gcc and clang:

    template <typename T, typename Derived>
    class varU
    {
        protected:
        varU() = default;
    
        Derived& operator=(T val)
        {
            static_cast<Derived*>(this)->set(val);
            return *static_cast<Derived*>(this);
        }
    };
    
    template <typename ...Ts>
    class var : public varU<Ts, var<Ts...>>...
    {
        template <typename T, typename Derived>
        friend class varU;
    
        public:
         using varU<Ts, var<Ts...>>::operator=...;  // Something like this?
    
        private:
        template <typename T>
        void set(const T& v)
        {
        }
    };
    
    int main() {
        var<int, float> x;
        x = 5;
        x = 5.f;
    
        return 0;
    }
    

    See live code here.