2008-11-25 18 views
4

我想要boost::any_cast<T>僅在any的類型沒有隱式轉換爲T時拋出異常。如果any的類型不是T,則正常行爲似乎是拋出異常,而不考慮隱式轉換。boost :: any_cast - 僅當隱式轉換不可用時才拋出?

例子:

boost::any a = 1; 
boost::any_cast<int>(a); // This succeeds, and rightfully so 
boost::any_cast<long>(a); // I don't want this to throw 
boost::any_cast<Widget>(a); // I want this to throw 

誰能告訴我,如果有一個簡單的方法來得到我想要的功能,或者更好的是給我一個很好的理由,爲什麼現有的行爲是現在這個樣子?

回答

5

那麼你不能這樣做。 any機制的工作原理是這樣的:

struct base { 
    virtual ~base() { } 
}; 

template<typename T> 
struct concrete_base : base { 
    T t; 
    concrete_base(T t):t(t) { } 
}; 

struct my_any { 
    base * b; 

    template<typename T> 
    my_any(T t):b(new concrete_base<T>(t)) { } 

    template<typename T> 
    T any_cast() { 
     concrete_base<T> * t = dynamic_cast< concrete_base<T>* >(b); 
     if(!t) throw bad_any_cast(); 
     return t->t; 
    } 
}; 

我希望很清楚上述做了什麼。沒有辦法,你可以做你正在尋找我認爲。原因是沒有關於可能在此證明有用的類型的信息。 RTTI不提供它。

-1

any_cast無法做到這一點,但如果基類和派生類型是完整的(它們通常適用於層次結構中的類型),您可以實現自己的系統,它通過throw和catch進行轉換,指向派生類型的指針可以被捕獲爲基指針類型。

+1

`throw`和`catch`是爲了處理錯誤,而不是圍繞在別人的界面上故意限制。 (我不知道他們在這裏是否有必要/有用,但我知道這個想法/建議在任何情況下都是不好的。)如果有人想要一個隱式轉換的類型擦除容器,那麼他們應該寫他們的擁有。 – 2016-09-27 06:57:27