0

I'm still going through std::error_code and am now trying to make my list of error enums equivalent to std::error_code. I'm following what's on this tutorial but for some reason I can't make it work, I always end up with the error No viable conversion from 'my_project::my_error' to 'std::error_code'.

This is what I'm working with:

#include <system_error>
#include <string>

namespace std {

  enum class my_error;

  template <>
  struct is_error_condition_enum<my_error> : public true_type {};
}

namespace my_project {
  enum class my_error {
    warning = 45836431
  };

  namespace internal {
    struct my_error_category : public std::error_category {
      const char* name() const noexcept override {
        return "AAA";
      }
      std::string message(int ev) const noexcept override {
        const std::string message = "BBB";
        return message;
      }
    };
  }
}

inline std::error_code make_error_code(const my_project::my_error &e) {
  return {static_cast<int>(e), my_project::internal::my_error_category()};
};

int main()
{
  std::error_code ec = my_project::my_error::warning;
}
ruipacheco
  • 15,025
  • 19
  • 82
  • 138
  • You wrote `make_error_code()` but are not using it. –  Aug 24 '17 at 15:58
  • 1
    Also, I think the way you extend the std namespace causes undefined behaviour: https://stackoverflow.com/questions/41062294/c-when-is-it-ok-to-extend-the-std-namespace , http://en.cppreference.com/w/cpp/language/extending_std – KjMag Aug 24 '17 at 16:06
  • @Frank According to the tutorial I shouldn't need it? Maybe I'm misreading it. – ruipacheco Aug 24 '17 at 16:08
  • @KjMag Tutorial says it's fine? – ruipacheco Aug 24 '17 at 16:08
  • @KjMag specializing a `std` template is an explicit exception listed in your second link. –  Aug 24 '17 at 16:10
  • 1
    @Frank But the OP has declared a class (my_error) inside the std namespace apart from template specialization. As for the tutorial, they declare their class outside the std namespace. – KjMag Aug 24 '17 at 16:12

1 Answers1

1

This works:

#include <system_error>
#include <string>

namespace my_project {
  enum class my_error {
    warning = 45836431
  };
}

namespace std {
  // you had a typo here, and you defined a different std::my_error class
  template <>
  struct is_error_code_enum<my_project::my_error> : public true_type {};
}

namespace my_project {

  namespace internal {
    struct my_error_category : public std::error_category {
      const char* name() const noexcept override {
        return "AAA";
      }
      std::string message(int ev) const noexcept override {
        const std::string message = "BBB";
        return message;
      }
    };
  }

inline std::error_code make_error_code(const my_project::my_error &e) {
  return {static_cast<int>(e), my_project::internal::my_error_category()};
};
}

int main()
{
  std::error_code ec = my_project::my_error::warning;
}

Clang's error messages put me on the right track because it told me why it was not using the right constructor.

PaulR
  • 3,587
  • 14
  • 24