2011-08-07 32 views
7

如果我的基類具有函數func(int),並且我的派生類具有函數func(double),則導出的func(double)將隱藏base::func(int)。我可以用using使底座的版本到重載的派生的列表:我需要類似「使用Base :: *;」

struct base 
{ 
    void func(int); 
}; 

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

OK,太好了。但是如果我不確定base是否有func()?即因爲我在做模板元編程,所以我不確定base是什麼,但是我想把它的功能提升到相同的水平 - 如果它們存在的話。即,上面的例子中改變爲:

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 :-(

我需要using_ifboost::enable_if。似乎不可能...

在此先感謝。

+1

你最終想做什麼?什麼是派生的'用於? –

+0

我正在構建可以實現某些功能的類,具體取決於它們的使用方式/位置。這基本上只是重構,在一定程度上 - 即不是編寫XWithFeatureA類,XWithFeatureB類,XWithFeatureAandB類......這會變成許多樣板類,我希望有X ,其中feature_traits決定使用哪些特徵。 – tony

+0

對於系統中的對象,諸如'允許偵聽器','具有自定義setter'等的功能。我不認爲我可以(或者被允許)描述它,以至於你確信具有可選功能的系統實際上是有意義的。 – tony

回答

0

我想我需要做的是這樣

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; 
    ... 
}; 

哎呀。當然這不起作用,因爲dummy_func不是derived的基數。在我的情況下,我可以在必要時將它從中派生出來。但仍然不盡如人意。

+0

我想這不是'使用Base :: *',但'*' - '使用這個類的所有東西',如果可能的話,也會給我什麼我通緝。 – tony

1

既然你願意把using報表到您的派生類中,我假設你知道beforehands哪些成員,你可以有興趣在帶來可以使用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; } 
}; 

對不起爲所有打印語句。現在,如果你嘗試

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

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

你應該看到

構造函數:與
男星得出:沒有
FUNC衍生(INT)
FUNC(雙)
FUNC(雙)
func(double)

Obv如果你嘗試測試幾個功能,這將是怪異的。如果我在做這樣的mixin風格的編程,我可能寧願使用具有不同名稱的函數來實現不同的功能,這樣它們就不會互相隱藏 - 那麼公有繼承就是所需要的。無論如何有趣的問題。

相關問題