首页 > 解决方案 > 表达式模板需要冗余重载

问题描述

我正在创建一个基于表达式模板的简单数组类。在下面的代码中,我需要创建operator=函数的重载,以使其工作,即使它是上面函数的精确副本。原因是(根据 GCC),因为编译器禁用了默认复制分配。有没有办法避免过载并通过模板化函数将其隧道化?

主程序:

#include <iostream>
#include "Array.hpp"

int main()
{
    const int itot = 10;
    Array_1d a(itot);
    Array_1d b(itot);

    for (int i=0; i<itot; ++i)
        a(i) = i;

    b = 0.;

    a.print();

    b(7,10) = a(1,4);
    b.print();
}

标题Array_1d

#include <vector>
#include <iostream>

class Array_1d
{
    public:
        Array_1d(const int itot) :
            itot(itot), data(nullptr)
        {
            data = new double[itot];
        }

        Array_1d(const int itot, double* data) :
            itot(itot), data(data)
        {}

        // Deletion needs to be solved.
        ~Array_1d()
        {}

        void print()
        {
            for (int i=0; i<itot; ++i)
                std::cout << i << " = " << (*this)(i) << std::endl;
        }

        double& operator()(const int i) { return data[i]; }
        double operator()(const int i) const { return data[i]; }

        Array_1d operator()(const int is, const int ie) const { return Array_1d(ie-is, data+is); }

        template<class T>
        inline Array_1d& operator= (const T& __restrict__ expression)
        {
            for (int i=0; i<itot; ++i)
                (*this)(i) = expression(i);

            return *this;
        }

        // Why is this specialization necessary?
        inline Array_1d& operator= (const Array_1d& __restrict__ expression)
        {
            for (int i=0; i<itot; ++i)
                (*this)(i) = expression(i);

            return *this;
        }

        inline Array_1d& operator= (const double value)
        {
            for (int i=0; i<itot; ++i)
                (*this)(i) = value;

            return *this;
        }

    private:
        const int itot;
        double* data;
};

标签: c++templatestemplate-meta-programming

解决方案


Even though you did not write it explicitly, the implicitly deleted copy-assignment operator still "exists" and is a better match than the templated one, which is why it is chosen when you assign from a Array_1d.

You can explicitly call the templated method from the non-templated one:

Array_1d& operator= (const Array_1d& __restrict__ expression)
{
    return this->operator=<Array_1d>(expression);
}

推荐阅读