2015-04-16 13 views
11

Xét đoạn mã sau sử dụng lớp ngoại lệ tăng của:.Tôi có thể sao chép-xây dựng một tăng :: ngoại lệ với các thông tin lỗi?

class exception : virtual public boost::exception { 
    // ... 
}; 

template<typename Exc> 
class exception_impl : virtual public std::exception 
        , public Exc { 
public: 
    exception_impl(const Exc& exc) : Exc(exc) {} 
    virtual const char* what() const throw() {return "blah";} 
}; 

(Trên thực tế mã này là phức tạp hơn Ví dụ, exception_impl chỉ xuất phát từ std::exception nếu sau này không phải là đã là một lớp cơ sở trực tiếp hoặc gián tiếp của Exc . Nhưng điều này chỉ lãng từ vấn đề tôi có, vì vậy tôi đã bỏ qua nó)


vì điều này, bây giờ tôi có thể lấy được các lớp ngoại lệ của riêng tôi:.

class some_exception : public exception { 
    // ... 
}; 

Và sử dụng chúng:

struct tag_test_int; 
typedef boost::error_info<tag_test_int,int> test_int_info; 

void f() 
{ 
    boost::throw_exception(exception_impl<some_exception>() << test_int_info(42)); 
} 

Tuy nhiên, nó chỉ ra rằng ngoại trừ kết quả không có đối tượng test_int_info. Vì vậy, tôi đã thay đổi các nhà xây dựng exception_impl cung cấp một số thông tin chẩn đoán:

exception_impl(const Exc& exc) 
    : Exc(exc) { 
     std::cerr << "========================================================================\nexc:\n"; 
     std::cerr << boost::diagnostic_information(exc); 
     std::cerr << "========================================================================\n*this:\n"; 
     std::cerr << boost::diagnostic_information(*this); 
     std::cerr << "========================================================================\n"; 
    } 

này thực sự cho thấy rằng những thông tin bị mất khi tôi sao chép các đối tượng Exc vào exception_impl cơ sở lớp đối tượng:

 
======================================================================== 
exc: 
Throw location unknown (consider using BOOST_THROW_EXCEPTION) 
Dynamic exception type: some_exception 
[tag_test_int*] = 42 
======================================================================== 
*this: 
Throw location unknown (consider using BOOST_THROW_EXCEPTION) 
Dynamic exception type: exception_impl 
std::exception::what: "blah" 

IIRC, các đối tượng ngoại lệ phải được sao chép theo tiêu chuẩn và, bỏ qua tối ưu hóa có thể có, kết quả của một biểu thức ném được sao chép. Vì vậy, ngoại lệ của boost phải được sao chép và chắc chắn họ không mất thông tin của họ trên đường đi. Tôi phải thiếu một cái gì đó khá rõ ràng ở đây.

Tôi đang làm gì sai?

+0

có lẽ có liên quan http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2106.html và http://www.open-std.org/jtc1/sc22/wg21 /docs/papers/2007/n2179.html – sehe

+2

OK, do đó, vì một số lý do không giải thích được (không thể giải thích cho tôi), vấn đề sẽ biến mất khi tôi lấy được 'ngoại lệ' ___ không phải hầu như ___ từ' boost :: exception'. Tôi bối rối và rất thích nghe lời giải thích. – sbi

+0

@sehe: Tôi đã lướt qua các tài liệu nhưng không thấy bất kỳ điều gì có liên quan. Bạn đang ám chỉ cái gì? – sbi

Trả lời

3

Làm việc perfecly tốt cho tôi:
(tôi đã có thêm một constructor mặc định để exception_impl)

#include <iostream> 
#include <exception> 
#include <boost/exception/all.hpp> 

using std::cout; 

class myException : public virtual boost::exception { 

}; 

template <class T> 
class exception_impl : public virtual std::exception, public T { 
public: 
    exception_impl() {} 
    exception_impl(const T& ex) : T(ex) {} 
    virtual const char* what() const throw() {return "blah";} 
}; 

class some_exception : public myException { 

}; 

struct tag_test_int; 
typedef boost::error_info<tag_test_int,int> test_int_info; 

void f() 
{ 
    boost::throw_exception(exception_impl<some_exception>() << test_int_info(42)); 
} 

int main() { 

    try { 
     f(); 
    } catch (boost::exception& e) { 
     cout << boost::diagnostic_information(e); 
    } 

    return 0; 
} 

Output:

Throw location unknown (consider using BOOST_THROW_EXCEPTION) 
Dynamic exception type: N5boost16exception_detail10clone_implI14exception_implI14some_exceptionEEE 
std::exception::what: blah 
[P12tag_test_int] = 42 

Biên soạn sử dụng:

  • g ++ (Ubuntu 4.9.2-0ubuntu1 ~ 14.04) 4.9.2
  • boost 1.55

Tôi nghĩ rằng vấn đề là bạn xuất thông tin chẩn đoán bên trong hàm tạo và tag_test_int không được đặt máy bay phản lực.

+0

Vì vậy, tôi trở về nhà, nhưng đã hết thời gian. Vì vậy, thay vì lãng phí một nửa số tiền thưởng, tôi đưa nó cho câu trả lời này, vì nó là người duy nhất tôi có. Tôi sẽ đi và nhìn vào mã khi tôi tìm thấy thời gian tại nơi làm việc để làm như vậy và cố gắng tìm ra cách mã của tôi khác với mã của bạn. Cảm ơn bạn và mọi người khác đã xem xét điều này! – sbi

+0

Cuối cùng tôi đã dành thời gian để tìm kiếm điều này. [Mã này] (http://coliru.stacked-crooked.com/a/12273f417d917419) hoạt động như mong đợi trên coliru, nhưng nó không hoạt động trên nền tảng của tôi. Tôi không thể không giả định rằng điều này là bởi vì chúng tôi đang mắc kẹt với tăng 1.52, được cho là có một lỗi. (Chúng tôi cũng đang sử dụng một trình biên dịch cũ hơn, nhưng tôi nghi ngờ rằng điều này sẽ gây ra lỗi như vậy.) Vì không có gì chúng tôi có thể làm, chúng tôi có, trong thời gian này, để lấy được không hầu như. _Thanks một lần nữa cho nỗ lực của bạn _ – sbi

+0

Tôi đã tăng 1,48 trên hệ thống dev của tôi và nó hoạt động giống như trên cliru. Vì vậy, có lẽ bạn phải có một cái nhìn tại trình biên dịch của bạn, tôi là gcc phiên bản 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5). – Sven

Các vấn đề liên quan