Попытка сделать мое перечисление эквивалентным std::error_code

Я все еще просматриваю std::error_code и сейчас пытаюсь чтобы мой список перечислений ошибок был эквивалентен std::error_code. Я следую указаниям этого руководства, но по какой-то причине не могу это работает, я всегда получаю ошибку No viable conversion from 'my_project::my_error' to 'std::error_code'.

Вот с чем я работаю:

#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;
}

person ruipacheco    schedule 24.08.2017    source источник
comment
Вы написали make_error_code(), но не используете его.   -  person Frank    schedule 24.08.2017
comment
Кроме того, я думаю, что способ расширения пространства имен std вызывает поведение undefined: stackoverflow.com/questions/41062294/ , en.cppreference.com/w/cpp/language/extending_std   -  person KjMag    schedule 24.08.2017
comment
@Frank Согласно учебнику, мне это не нужно? Может быть, я неправильно читаю.   -  person ruipacheco    schedule 24.08.2017
comment
Учебник @KjMag говорит, что все в порядке?   -  person ruipacheco    schedule 24.08.2017
comment
@KjMag, специализирующийся на шаблоне std, является явным исключением, указанным во второй ссылке.   -  person Frank    schedule 24.08.2017
comment
@Frank Но OP объявил класс (my_error) внутри пространства имен std, помимо специализации шаблона. Что касается учебника, они объявляют свой класс вне пространства имен std.   -  person KjMag    schedule 24.08.2017


Ответы (1)


Это работает:

#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 указали мне правильный путь, потому что они сказали мне, почему он не использует правильный конструктор.

person PaulR    schedule 24.08.2017