This bugzilla service is closed. All entries have been migrated to https://gitlab.com/libeigen/eigen
Bug 920 - VC++ 2015 compiler error: deleted copy assignment operator for Block (and base classes)
Summary: VC++ 2015 compiler error: deleted copy assignment operator for Block (and bas...
Status: RESOLVED FIXED
Alias: None
Product: Eigen
Classification: Unclassified
Component: Core - general (show other bugs)
Version: 3.3 (current stable)
Hardware: All Windows
: Normal Compilation Problem
Assignee: Nobody
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-12-16 15:13 UTC by Michael Hofmann
Modified: 2019-12-04 13:59 UTC (History)
3 users (show)



Attachments

Description Michael Hofmann 2014-12-16 15:13:41 UTC
I am failing to compile the following simple program using VC++ 2015 Preview and Eigen changeset ccf109e3b393 (tip, as of writing):

---
#include <Eigen/Core>

int main()
{
    Eigen::Matrix3f m = Eigen::Matrix3f::Zero();
    Eigen::Matrix3f n = Eigen::Matrix3f::Zero();
    m.block<2, 2>(0, 0) = n.block<2, 2>(0, 0);
}
---

The compiler complains that the copy assignment operator of Block<> is deleted:

1>test.cpp(66): error C2280: 'Eigen::Block<Derived,2,2,false> &Eigen::Block<Derived,2,2,false>::operator =(const Eigen::Block<Derived,2,2,false> &)': attempting to reference a deleted function
1>          with
1>          [
1>              Derived=Eigen::Matrix<float,3,3,0,3,3>
1>          ]
1>  eigen\eigen\src\core\block.h(148): note: compiler has generated 'Eigen::Block<Derived,2,2,false>::operator =' here
1>          with
1>          [
1>              Derived=Eigen::Matrix<float,3,3,0,3,3>
1>          ]

which might or might not be a valid complaint, since the class contains non-static const variables.
See also http://en.cppreference.com/w/cpp/language/as_operator#Deleted_implicitly-declared_copy_assignment_operator.

I have tried adding an explicit definition for the copy assignment operator by calling the respective operator of its base class and returning *this, but this operation becomes viral. The compiler appears to require explicit copy assignment operator definitions for all base classes. (And I don't really want to patch this myself for our code base, because I'd probably get it wrong...)

What is the best solution here - just adding explicit definitions for all copy assignment operators up the inheritance hierarchy? Or something else?
Comment 1 Christoph Hertzberg 2014-12-16 15:56:14 UTC
(In reply to Michael Hofmann from comment #0)
> I have tried adding an explicit definition for the copy assignment operator
> by calling the respective operator of its base class and returning *this,

That should be exactly what line 110 does:
https://bitbucket.org/eigen/eigen/src/ccf109e3b393/Eigen/src/Core/Block.h?at=default#cl-110

But that definition is not enabled if EIGEN_COMP_MSVC_STRICT is true.
Could you change line 595 in src/Core/util/Macros.h to:

#if EIGEN_COMP_MSVC_STRICT && EIGEN_COMP_MSVC < 1900

and report what happens?
Comment 2 Michael Hofmann 2014-12-16 17:42:15 UTC
My version of src/Core/util/Macros.h (from tip of default) doesn't even have that many lines (it has 468), but I have changed line 340 like this:

$ hg diff
diff -r 3cc5093598e5 src/Eigen/Eigen/src/Core/util/Macros.h
--- a/src/Eigen/Eigen/src/Core/util/Macros.h    Tue Dec 16 15:49:46 2014 +0100
+++ b/src/Eigen/Eigen/src/Core/util/Macros.h    Tue Dec 16 17:15:00 2014 +0100
@@ -337,7 +337,7 @@
 // just an empty macro !
 #define EIGEN_EMPTY

-#if defined(_MSC_VER) && (!defined(__INTEL_COMPILER))
+#if defined(_MSC_VER) && (_MSC_VER < 1900) && (!defined(__INTEL_COMPILER))
 #define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
   using Base::operator =;
 #elif defined(__clang__) // workaround clang bug (see http://forum.kde.org/viewtopic.php?f=74&t=102653)

This fixes the above compiler error but triggers another error further up the chain, in MapBase<>:

1>eigen\src/Core/MapBase.h(246): error C3083: '{ctor}': the symbol to the left of a '::' must be a type

and the code in question is:

    EIGEN_DEVICE_FUNC
    Derived& operator=(const MapBase& other)
    {
      Base::Base::operator=(other);    // line 246
      return derived();
    }

If I now change line 246 to 'Base::operator=(other);', then the compiler also complains about a deleted copy assignment operator, in MapBase<Derived, 0> (its base class?):

1>eigen\eigen\src/Core/MapBase.h(246): error C2280: 'Eigen::MapBase<Derived,0> &Eigen::MapBase<Derived,0>::operator =(const Eigen::MapBase<Derived,0> &)': attempting to reference a deleted function
1>          with
1>          [
1>              Derived=Eigen::Block<Eigen::Matrix<double,-1,1,0,-1,1>,-1,1,false>
1>          ]
1>  eigen\eigen\src/Core/MapBase.h(174): note: compiler has generated 'Eigen::MapBase<Derived,0>::operator =' here
1>          with
1>          [
1>              Derived=Eigen::Block<Eigen::Matrix<double,-1,1,0,-1,1>,-1,1,false>
1>          ]
Comment 3 Christoph Hertzberg 2014-12-16 18:12:28 UTC
The current version of Macros.h should look like this:
https://bitbucket.org/eigen/eigen/src/1ab289b0ce3f/Eigen/src/Core/util/Macros.h

Please make sure your version is up to date.

The Base::Base problem seems to be related to Bug 821. Try changing that line to:

  typedef Base Base_;
  Base_::Base::operator=(other);
Comment 4 Michael Hofmann 2014-12-17 11:38:21 UTC
Yep, that does the trick.

Changing line 242 in MapBase.h to
  typedef Base Base_;
  Base_::Base::operator=(other);
while at the same time changing line 595 in Macros.h to
  #if EIGEN_COMP_MSVC_STRICT && EIGEN_COMP_MSVC < 1900
fixes this bug.
Comment 6 Nobody 2019-12-04 13:59:31 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to gitlab.com's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.com/libeigen/eigen/issues/920.

Note You need to log in before you can comment on or make changes to this bug.