2012-08-09 36 views
3

爲什麼不如下編譯:理解的boost ::變種

void f(int8_t a) 
{ 
} 

void f(int16_t a) 
{ 
} 

typedef boost::variant<int8_t, int16_t> AttrValue; 

int main() 
{ 
    AttrValue a; 
    a = int8_t(1); 
    f(a); 
} 

隨着編譯器錯誤:

error C2665: 'f' : none of the 2 overloads could convert all the argument types 
could be 'void f(int8_t)' 
or 'void f(int16_t)' 

然而,這是確定:

std::cout << a; // f(a); 

在哪裏std :: ostream &運營商< <(std :: ostream &,const AttrValue &)定義,爲什麼定義?

+0

什麼是boost用於?它有什麼作用?線程? GPU編程? – 2012-08-09 12:34:25

+0

@tuğrulbüyükışık - http://www.boost.org/ – 2012-08-09 12:35:55

+0

@tuğrulbüyükışık:boost是迄今爲止最知名的標準之外的C++庫。 www.boost.org – Gorpik 2012-08-09 12:36:48

回答

9

重載決議發生在編譯時,當你的boost::variant實例可能包含任何類型,所以編譯器無法知道是否要撥打void f(int8_t)void f(int16_t)

std::cout << a可以工作,因爲在任何情況下,它都會調用相同的函數std::ostream &operator<<(std::ostream &, const AttrValue &),該函數在實例的運行時類型中進行調度。

你需要寫一個訪客進行調度:

struct f_visitor: public boost::static_visitor<void> 
{ 
    template<typename T> void operator()(T t) const { return f(t); } 
}; 

boost::apply_visitor(f_visitor(), a); 
+0

std :: ostream&operator <<(std :: ostream&,const AttrValue&)定義在哪裏? – Baz 2012-08-09 12:40:23

+0

@Baz它由'boost :: variant'定義。我將添加鏈接到文檔。 – ecatmur 2012-08-09 12:43:19

+0

所以一個operator << visitor是由boost :: variant實現的嗎?是爲了方便而添加的嗎? – Baz 2012-08-09 12:44:30

2

嗯,有一件事你是給自己分配 a。並且由於沒有任何重載需要 boost::variant類型,所以編譯器當然無法找到正確的函數。

此外,您可能需要使用boost::get獲得價值:

f(boost::get<int8_t>(a)); 
+0

在操作中固定賦值給自己。 – Baz 2012-08-09 12:42:13

0

它發生operator<<boost::variant定義,所以編譯器不需要執行任何隱式類型轉換。另一方面,對於您的f()函數,它不知道要選擇哪個轉換。