문제

연산자 <<을 사용하여 메시지를 만들 수 있도록 stringstream을 도출하고 싶습니다. API는 다음과 같습니다.

error("some text") << " more text " << 42 << std::endl;

이것은해야합니다

throw "some text more text 42"

따라서 내가 한 일은 '오버 플로우'메소드를 과부하시키고 타조 (& ErrorBuf)를 생성하는 ErrorBuf (StreamBuf에서 상속)를 만드는 것입니다. Basic_ostringstream이나 무언가를 상속하지 말아야하는지 궁금합니다 ...

도움이 되었습니까?

해결책

내가 좋아하는 매크로를 다시 여기로 밟을 것입니다.

#define ATHROW( msg )                                               \
{                                                                   \
    std::ostringstream os;                                          \
    os << msg;                                                      \
    throw ALib::Exception( os.str(), __LINE__, __FILE__ );          \
}                                                                   \

사용:

ATHROW( "Invalid value: " << x << " should be " << 42 );

예외 유형은 내 도서관에서 나온 것이지만 아이디어를 얻는 것 같습니다. 이것은 자신의 스트림 클래스를 도출하는 것보다 훨씬 간단하며 OP << ()로 많은 불쾌한 합병증을 피합니다.

다른 팁

다음과 같은 작업을 수행하여 쉽게 할 수 있습니다.

class error_builder
{
public:
    error_builder(const std::string& pMsg = "")
    {
        mMsg << pMsg;
    }

    ~error_builder(void)
    {
        throw std::runtime_error(mMsg.str());
    }

    template <typename T>
    error_builder& operator<<(const T& pX)
    {
        mMsg << pX;

        return *this;
    }

private:
    std::stringstream mMsg;    
};


error_builder("some text") << " more text " << 42 << std::endl;

당신은 당신처럼 끈을 던져서는 안됩니다. std::runtime_error. 모든 예외는에서 파생되어야합니다 std::exception, 어느 runtime_error 그렇게하면 모든 의미있는 예외는 const와 함께 잡힐 수 있습니다. std::exception&.

이것은 전체 표현이 끝날 때까지 일시적인 삶 때문에 작동합니다.

일부 운영자는 GMAN의 솔루션에서 누락되었습니다.

class error {
   public:
   explicit error(const std::string& m = "") :
          msg(m, std::ios_base::out | std::ios_base::ate)
   {}

   ~error() {
      if(!std::uncaught_exception()) {
         throw std::runtime_error(msg.str());
      }
   }

   template<typename T>
   error& operator<<(const T& t) {
      msg << t;
      return *this;
   }

   error& operator<<(std::ostream& (*t)(std::ostream&)) {
      msg << t;
      return *this;
   }
   error& operator<<(std::ios& (*t)(std::ios&)) {
      msg << t;
      return *this;
   }
   error& operator<<(std::ios_base& (*t)(std::ios_base&)) {
      msg << t;
      return *this;
   }
   private:
   std::ostringstream msg;
};

나는 보통 내 자신의 예외 수업을 만듭니다. 당신은 단지 무시하면됩니다 what() 원하는만큼의 생성자를 제공 할 수 있습니다. 오류 메시지를 작성하려면 위와 같이 vasprintf (사용 가능한 경우) 또는 std :: ostringstream을 사용하십시오.

예는 다음과 같습니다.

class CustomException : public std::exception {
private:
    const std::string message;
public:
    CustomException(const std::string &format, ...) {
        va_list args;
        va_start(args, format);
        char *formatted = 0;
        int len = vasprintf(&formatted, format.c_str(), args);
        if (len != -1) {
            message = std::string(formatted);
            free(formatted);
        } else {
            message = format;
        }
        va_end(args);
    }
    const char *what() const {
        return message.c_str();
    }
};

vasprintf가없는 경우 스택에 버퍼와 함께 vsnprintf를 사용할 수도 있습니다 ...

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top