How to utilize template copy&move constructor and assignment operator?

拜拜、爱过 提交于 2020-02-03 07:54:13

问题


Consider the following C++ code with my failed attempt to avoid preference of non-template copy&move constructors and assignment operators:

template<typename T> class A {
public:
    A() { /* implementation here */ }

    // Remove from the overloads the default copy&move constructors and assignment operators
    A(const A&) = delete;
    A& operator=(const A&) = delete;
    A(A&&) = delete;
    A& operator=(A&&) = delete;

    // I want these to be used e.g. by std::vector
    template<typename U> A(const A<U>& fellow) { /* implementation here */ }
    template<typename U> A& operator=(const A<U>& fellow) { /* implementation here */ }

    template<typename U> A(A<U>&& fellow) { /* implementation here */ }
    template<typename U> A& operator=(A<U>&& fellow) { /* implementation here */ }        
};

However, I get the following error

attempting to reference a deleted function

when trying to push A items to a vector or simply copy-construct like:

A<int> a1{};
A<int> a2(a1);

UPDATE1: I need template copy&move constructors and assignment operators, because the template argument really just controls some caching, so A<T1> can be safely assigned to A<T2>.


回答1:


You can make compiler happy by declaring deleted copy constructor / assignment operator with alternative signature which will not cause this overload to be selected but will prevent generation of constructor / assignment operator by compiler:

template<typename T> class A
{ public:
    A() { /* implementation here */ }

    // Remove from the implicit declaration of the default copy&move constructors and assignment operators
    A(A volatile const &) = delete;
    A & operator =(A volatile const &) = delete;

    // I want these to be used e.g. by std::vector
    template<typename U> A(A<U> const & fellow) { /* implementation here */ }
    template<typename U> A & operator =(A<U> const & fellow) { /* implementation here */ return *this;}

    template<typename U> A(A<U> && fellow) { /* implementation here */ }
    template<typename U> A & operator =(A<U> && fellow) { /* implementation here */ return *this; }        
};
int main()
{
    A<int> a1{};
    A<int> a2{a1};
    return 0;
}

online compiler

15.8.1 Copy/move constructors [class.copy.ctor]
1. A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments




回答2:


A minimal example of a copy constructor that delegate the execution to the template constructor using a second unused (and defaulted) argument

#include <iostream>

template <typename T>
struct A
 {
   A()
    { }

   A (A const & a0) : A{a0, 0}
    { }

   template<typename U>
   A (A<U> const &, int = 0)
    { std::cout << "template constructor" << std::endl; }
 };

int main()
 {
   A<int>  a0;
   A<int>  a1{a0};
 }

-- EDIT --

The OP asks

What about operator=? Trying to add a dummy parameter gives compiler errors binary 'operator =' has too many parameters and 'operator =' cannot have default parameters

For operator=() I propose to "delegate" (not in the meaning of delegating constructor, in this case) both operators to a normal method; a template one.

Something as

   template <typename U>
   A & assign (A<U> const &)
    { /* do assignment */ return *this; }

   A & operator= (A const & a0)
    { return assign(a0); }

   template <typename U>
   A & operator= (A<U> const & a0)
    { return assign(a0); }  

Maybe the assign() method can be a private one.

Or better, as suggested by Jarod42 (thanks), directly calling the template operator from the not-template one

template <typename U>
A & operator= (A<U> const & a0)
 { /* do assignment */ return *this; }

A & operator= (A const & a0)
 { return operator=<T>(a0); }


来源:https://stackoverflow.com/questions/54050890/how-to-utilize-template-copymove-constructor-and-assignment-operator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!