2011-08-07 43 views
7

Nếu lớp cơ sở của tôi có chức năng func(int) và lớp dẫn xuất của tôi có hàm func(double), nguồn gốc func(double) ẩn base::func(int). Tôi có thể sử dụng using để mang lại phiên bản gốc vào danh sách của Rút ra quá tải:Tôi cần một cái gì đó như "using Base :: *;"

struct base 
{ 
    void func(int); 
}; 

struct derived : base 
{ 
    using base::func; 
    void func(double); 
} 

OK, tuyệt vời. Nhưng nếu tôi không chắc chắn liệu base có một số func() hay không? tức là bởi vì tôi đang làm mẫu lập trình meta, tôi không thực sự chắc chắn những gì base là, nhưng tôi muốn mang lại chức năng của nó lên đến cùng cấp - nếu chúng tồn tại. ví dụ: thay đổi ví dụ trên thành:

struct base_with 
{ 
    void func(int); 
}; 
struct base_without 
{ 
}; 

template <typename Base> 
struct derived : Base 
{ 
    using Base::func; // if Base has a func(), I want to bring it in 

    void func(double); 
} 

derived<base_with> testwith; // compiles 
derived<base_without> testwithout; // fails :-(

Tôi cần using_if như boost::enable_if. Có vẻ như không thể ...

Xin cảm ơn trước.

+1

Bạn muốn làm gì cuối cùng? 'Có nguồn gốc ' được sử dụng cho là gì? –

+0

Tôi đang xây dựng các lớp học tùy chọn triển khai một số tính năng, tùy thuộc vào cách thức/nơi chúng được sử dụng. Về cơ bản chỉ là tái cấu trúc, ở một mức độ nào đó - tức là thay vì viết lớp XWithFeatureA, XWithFeatureB, XWithFeatureAandB, ... chuyển thành nhiều lớp soạn sẵn, tôi muốn có X trong đó feature_traits quyết định các tính năng nào được sử dụng. – tony

+0

Các tính năng là những thứ như 'cho phép người nghe', 'có những người định cư tùy chỉnh', v.v. đối với một đối tượng trong một hệ thống. Tôi không nghĩ rằng tôi có thể (hoặc được phép) mô tả nó đủ đến mức mà bạn sẽ được thuyết phục rằng một hệ thống với các tính năng tùy chọn thực sự có ý nghĩa. – tony

Trả lời

0

Tôi đoán tôi cần phải làm một cái gì đó giống như

struct dummy_func 
{ 
private: 
    struct dumb_type {}; 

// interesting: does this need to be public? 
public: 
    // use a type that no one can see, so func is never chosen by ADT 
    // and vararg just for paranoia 
    void func(dumb_type, dumb_type, dumb_type,...) { }; 
}; 

... 
template <typename T> 
struct has_func 
{ 
    enum { value = /* insert metaprogramming magic that checks for T::func */ } 
}; 

template <typename Base> 
struct derived : Base 
{ 
    using enable_if<has_func<Base>, Base, dummy_func>::type::func; 
    ... 
}; 

Xin lỗi. Tất nhiên điều này không hiệu quả vì dummy_func không phải là cơ số của derived. Trong trường hợp của tôi, tôi có thể làm cho nó xuất phát từ nó khi cần thiết. Nhưng vẫn chưa đạt yêu cầu.

+0

Tôi đoán nó không giống như 'using Base :: *', nhưng '*' - 'sử dụng mọi thứ từ lớp này', nếu có thể, cũng sẽ cho tôi cái tôi truy nã. – tony

1

Kể từ khi bạn sẵn sàng đặt using báo cáo vào lớp được thừa kế của bạn, tôi giả sử bạn biết beforehands đó các thành viên bạn có thể được quan tâm để mang lại Bạn có thể làm điều này bằng boost::enable_if:.

struct base_with 
{ 
    void func(int) { cout << "func(int)" << endl; } 
}; 

struct base_without { }; 

// Custom traits, by default assume func() isn't present 
template <class T> struct has_func : public boost::false_type { }; 

template<> struct has_func<base_with> : public boost::true_type { }; 

// Again, if nothing else is known, assume absence of func(int) 
template <typename Base, class UseFunc = void> struct derived : Base 
{ 
    derived() { cout << "ctor: derived without" << endl; } 
    void func(double) { cout << "func(double)" << endl; } 
}; 

// Derived with func(int) 
template <typename Base> struct derived<Base, typename boost::enable_if< has_func<Base> >::type> : Base 
{ 
    using Base::func; 
    derived() { cout << "ctor: derived with" << endl; } 
    void func(double) { cout << "func(double)" << endl; } 
}; 

Xin lỗi cho tất cả các câu lệnh in. Bây giờ nếu bạn cố gắng

derived<base_with> testwith; 
derived<base_without> testwithout; 

testwith.func(10); 
testwith.func(10.5); 
testwithout.func(10); 
testwithout.func(10.5); 

bạn sẽ thấy

ctor: có nguồn gốc với
ctor: có nguồn gốc mà không
func (int)
func (double)
func (double)
func (double)

Obv iously, điều này sẽ nhận được monstrous nếu bạn cố gắng kiểm tra một số tính năng. Nếu tôi đang thực hiện lập trình mixin kiểu như vậy, tôi có thể sử dụng các hàm với các tên khác nhau cho các tính năng khác nhau để chúng không ẩn nhau - sau đó thừa kế công khai sẽ là tất cả những gì cần thiết. Câu hỏi thú vị trong mọi trường hợp.

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