Skip to content

No support for move-only types #3

@ArekPiekarz

Description

@ArekPiekarz

te doesn't seem to support move-only types, even though in the presence of move constructor and rvalue it will move the object and not use the copy constructor.

For example, given the following code that prints all calls to member functions of a tested class Circle:

#include "external/te/include/te.hpp"
#include <iostream>

using std::cout;

struct Drawable
{
    void draw(std::ostream &out) const
    {
        te::call([](auto const &self, auto &out) { self.draw(out); }, *this, out);
    }
};

struct Circle
{
    Circle() { cout << "Circle()\n"; }
    Circle(const Circle&) { cout << "Circle(const Circle&) ctor\n"; }
    Circle& operator=(const Circle&) { cout << "operator=(const Circle&)\n"; }
    Circle(Circle&&) { cout << "Circle(Circle&&)\n"; }
    Circle& operator=(Circle&&) { cout << "operator=(Circle&&)\n"; }
    ~Circle() { cout << "~Circle()\n"; }

    void draw(std::ostream &out) const { out << "Circle::draw\n"; }
};

void draw(const te::poly<Drawable>& drawable) { drawable.draw(cout); }

int main()
{
    Circle circle{};
    draw(std::move(circle));
}

we will get this output:

Circle()
Circle(Circle&&)
Circle::draw
~Circle()
~Circle()

But when we try to mark the copy constructor and copy assignment operator as deleted as below:

struct Circle
{
    Circle() { cout << "Circle()\n"; }
    Circle(const Circle&) = delete;
    Circle& operator=(const Circle&) = delete;
    Circle(Circle&&) { cout << "Circle(Circle&&)\n"; }
    Circle& operator=(Circle&&) { cout << "operator=(Circle&&)\n"; }
    ~Circle() { cout << "~Circle()\n"; }

    void draw(std::ostream &out) const { out << "Circle::draw\n"; }
};

we will get a compilation error:

main.cpp:33:19: error: invalid initialization of reference of type ‘const te::v1::poly<Drawable>&’ from expression of type ‘std::remove_reference<Circle&>::type {aka Circle}’
     draw(std::move(circle));
          ~~~~~~~~~^~~~~~~~
main.cpp:28:6: note: in passing argument 1 of ‘void draw(const te::v1::poly<Drawable>&)’
 void draw(const te::poly<Drawable>& drawable) { drawable.draw(cout); }
      ^~~~

Are there any plans to support noncopyable types?

Environment
OS: Ubuntu 17.10 x64
Compiler: GCC 7.2 x64

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions