Search code examples
c++c++17variadic-templates

Call base class operator= from derived in parameter pack


I have implemented a simple program in C++17, in which I try to call the base class operator= from a derived class using parameter expansion. But the program does not compile.

#include "pch.h"
#include <iostream>

class D
{
    public:
        D()
        {
            std::cout << "D ctror" << std::endl;
        }
        D  &  operator = (const D & other)
        {
            return *this;
        }
};
class C
{
    public:
        C()
        {
            std::cout << "C ctror" << std::endl;
        }
        C  &  operator = (const C & other)
        {
            return *this;
        }
};
class B
{
    public:
        B()
        {
        std::cout << "B ctror" << std::endl;
        }


        B  &  operator = (const B & other)
        {
            std::cout << "operator B" << std::endl;
            return *this;
        }
};


template<typename... Ts> class A: public Ts...
{ 
public:

    A():  Ts()...
    {
    }
    A  &  operator = (const A & other)
    {
        Ts::operator =(other);
        return *this;
    }

};

int main()
{

    A<B,C,D> a1;
    A<B,C,D> a2;
    a1 = a2;
}

The toolset that is used is the Visual Studio 2017 (v141)

The error that is generated is the following

error C3520: '=': parameter pack must be expanded in this context note: while compiling class template member function 'A &A::operator =(const A &)' note: see reference to function template instantiation 'A &A::operator =(const A &)' being compiled note: see reference to class template instantiation 'A' being compiled


Solution

  • You need to expand the parameter pack. How about a nice fold expression:

    (Ts::operator=(other), ...);
    

    This will expand Ts... and effectively create multiple calls to operator=, one for each type in the pack.