2012-06-20 22 views
6

Nếu tất cả các loại trong số boost::variant của tôi hỗ trợ cùng một phương pháp, có cách nào để gọi nó một cách tổng quát (tức là không gọi riêng cho từng phương thức của static_visitor)?Phương pháp gọi chung cho các loại tăng thêm :: Biến thể

Tôi đang cố gắng để có được một cái gì đó như thế này để làm việc:

class A 
{ 
    void boo() {} 
}; 

class B 
{ 
    void boo() {} 
}; 

class C 
{ 
    void boo() {} 
}; 

typedef boost::variant<A, B, C> X; 

void foo(X& d) 
{ 
    x.boo(); 
} 

nhưng nó thất bại trong việc biên dịch nói 'boo' : is not a member of 'boost::variant<T0_,T1,T2>'.

Hiện tại, tôi có một số lớp học tất cả được kế thừa từ giao diện để phương thức chia sẻ duy nhất của chúng có thể được sử dụng đa hình. Tôi cũng muốn có thể sử dụng các lớp học thông qua một khách truy cập như tất cả các phương pháp khác là duy nhất cho mỗi lớp cụ thể. Tôi đã hy vọng boost::variant có thể là một lựa chọn tốt hơn để triển khai cơ chế khách truy cập của chính tôi ở đây. Là nó?

Trả lời

4

Không có cách nào trực tiếp, nhưng bạn có thể làm cho static_visitor khá súc tích bằng cách sử dụng templating.

Modified từ các tài liệu thúc đẩy:

struct boo_generic : public boost::static_visitor<> 
{ 
    template <typename T> 
    void operator()(T & operand) const 
    { 
     operand.boo(); 
    } 
}; 

Bây giờ bạn có thể làm điều này:

boost::apply_visitor(boo_generic(), v); 

Infact bạn có thể khái quát này để có một con trỏ hàm của lớp cơ sở của bạn:

struct fn_generic : public boost::static_visitor<> 
{ 
    fn_generic(void (IBase::fn)()) : fn_(fn) {} 
    template<T> void operator() (T & op) const { op.*fn(); } 
} 

Sau đó, bạn có thể làm:

boost::apply_visitor(boo_generic(IBase::boo), v); 

Hoặc một cái gì đó như thế - Tôi có thể đã sai cú pháp con trỏ hàm của tôi sai, nhưng hy vọng bạn sẽ có được ý tưởng.