2013-04-03 33 views
1

我需要使用訪客類,例如class Visitor : public boost::static_visitor<> with boost :: variant?boost :: variant訪問者類是一個需求嗎?

如果不是,有沒有理由不使用訪客?是否有理由選擇訪客課程?

我問這個問題,因爲一個訪問者類似乎是使用boost :: variant的一個冗餘方面。

回答

5

您不是被迫使用訪問者,您可以使用get<T>()完美查詢基礎類型。

這導致了這樣的代碼:

int foo(boost::variant<int, std::string, Bar> const& v) { 
    if (int const* i = get<int>(&v)) { 
     return *i; 
    } 
    if (std::string const* s = get<std::string>(&v)) { 
     return boost::lexical_cast<int>(*s); 
    } 
    if (Bar const* b = get<Bar>(&v)) { 
     return b->toInt(); 
    } 

    std::abort(); // ? 
} 

哪個,可以說,醜......而且還具有應該添加一種類型的變種突然你需要檢查每一個使用它的問題在代碼中檢查你是不是在某處丟失if。另一方面,如果您使用變體,如果您未能處理某個案例(類型),則會收到編譯時錯誤通知。

在我看來,使用boost::static_visitor是無限的優越......雖然我已經使用get<T>()替代幾次;一般當我只需要檢查一個(或兩個)類型,並且不關心(所有其他)。另一種方法是使用訪問者的超載,但不一定更清潔。

+0

我能不是簡單地查詢使用'SomeVariantVariable.which()'的基本類型,將索引返回到'的typedef升壓::變體<類型1,類型2> variant_variable'聲明和指示哪些類型:類型1 = 0,Type2 = 1? – Mushy

+0

@Mushy:你可以,然後'切換'並調用'get()';但在這一點上,你只是重新實現了調用Visitor的代碼......除了如果有人在列表中間添加了一個類型,那麼索引就會移動,因此'get()'可能返回null,你必須考慮(或崩潰)。 –

0

如果想對變體進行一些操作,例如某些檢查,那麼您可能希望將其作爲訪問者進行操作。

struct to_str : boost::static_visitor<std::string> 
{ 
    template<class T> 
    std::string operator()(T const & x) const 
    { 
     return boost::lexical_cast<std::string>(x); 
    } 
}; 

。如果要另一方面,例如檢查它是否int,並用它做什麼,你可能會使用boost::get例如

if(const int * my_int = boost::get<int>(&my_var)) //no-throw form 
{ 
    //do smth with int 
}