lundi 2 juillet 2018

What should I implement, SetMember(const Member&), SetMember(Member) or SetMember(Member&&)?

Let Memeber be a class and let's assume I have no idea if it supports or need move semantics. For all intents and purposes let's say it isn't even specified/written yet. Which case of the SetMember functions should I implement in an Outer class, which has Member as a member?

If Member would not support move, I would do this:

class Member {
public:
    Member(Member&&) = delete;
    Member& operator=(Member&&) = delete;
};

class Outer {
    Member m_member;
public:
    void SetMember(const Member& o) { m_member = o.m_member; } // makes a copy
};

And if Member would support move, I would do this:

class Member {
public:
    Member(Member&&);
    Member& operator=(Member&&);
};

class Outer {
    Member m_member;
public:
    void SetMember(Member o) { m_member = std::move(o.m_member); } // makes a copy if needed
};

But since I do not know if it has move or not, do I need to implement both? Like this:

class Outer {
    Member m_member;
public:
    void SetMember(const Member& o) { m_member = o.m_member; } // makes a copy
    void SetMember(Member&& o) { m_member = std::move(o.m_member); } // makes no copy
};

Or should I do this?

class Outer {
    Member m_member;
public:
    template <class T>
    void SetMember(T&& o) { m_member = std::forward<T>(o.m_member); }
};

Why I'm not happy with these two solutions:

  • In the first solution I see code duplication, which is only needed because I don't know some implementation details of Member namely if it supports move or not.
  • The second solution leaves me with compilation errors instead of intelli sense errors whenever I try to use SetMember on a wrong type. Also I need a template just because some implementation details of Member.

What's the clean way to handle this situation?

Aucun commentaire:

Enregistrer un commentaire