Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tl::expected forces copy construction on non-copyable types #145

Open
E1pp opened this issue May 11, 2023 · 0 comments
Open

tl::expected forces copy construction on non-copyable types #145

E1pp opened this issue May 11, 2023 · 0 comments

Comments

@E1pp
Copy link

E1pp commented May 11, 2023

Hi,

The following snippet doesn't compile on clang 14.0.6

#include "expected.hpp"

class MoveOnly{
 public:
  MoveOnly() = default;

  // Non-copyable
  MoveOnly(const MoveOnly&) = delete;
  MoveOnly& operator=(const MoveOnly&) = delete;

  // Movable trivially
  MoveOnly(MoveOnly&&) = default;
  MoveOnly& operator=(MoveOnly&&) = default;
};

int main(){
  tl::expected<MoveOnly, std::error_code> a{};
  tl::expected<MoveOnly, std::error_code> b = std::move(a); // CE
}

Produced error point to the following snippet in the source code

#ifndef TL_EXPECTED_GCC49
template <class T, class E,
          bool = is_void_or<T, std::is_trivially_move_constructible<T>>::value
              &&std::is_trivially_move_constructible<E>::value>
struct expected_move_base : expected_copy_base<T, E> {
  using expected_copy_base<T, E>::expected_copy_base;
};

(expected.hpp:936 and onward). This code never checks if T is not copyable which causes the issue in the first place. Definition rules of TL_EXPECTED_GCC49

#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 &&              \
     !defined(__clang__))
#define TL_EXPECTED_GCC49
#endif

#if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 4 &&              \
     !defined(__clang__))
#define TL_EXPECTED_GCC54
#endif

#if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 5 &&              \
     !defined(__clang__))
#define TL_EXPECTED_GCC55
#endif

doesn't do anything if clang is chosen as a compiler. I believe, adding rules for different clang versions (or at least some common denominator for features in clang and gcc) will fix this issue without breaking anything in the meantime.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant