2017-02-24 64 views
0

對於不具名的標題,我真的不知道該怎麼稱呼我所問的內容。用派生類型重載函數的替代方法

我想實現以下目標:擁有一個基類類型的容器,其中包含派生類型的實例,訪問容器並根據所訪問的派生對象的類型調用函數重載。在之前的一個問題中,我詢問here我瞭解到我迄今爲止所考慮的靜態設計不起作用。我試過的方法是這樣的:

struct Int2TypeBase{ 
}; 

template <int v> 
struct Int2Type : public Int2TypeBase 
{ 
    enum 
    { 
     value = v 
    }; 
}; 


void f(const Int2Type<0>&){ 
    std::cout << "f(const Int2Type<0>&)" << "\n"; 
} 

void f(const Int2Type<1>&){ 
    std::cout << "f(const Int2Type<1>&)" << "\n"; 
} 


int main(){ 
    using namespace std; 

    std::vector<std::reference_wrapper<Int2TypeBase>> v; 

    Int2Type<0> i2t_1; 
    v.emplace_back(i2t_1); 
    Int2Type<1> i2t_2; 
    v.emplace_back(i2t_2); 

    auto x0 = v[0]; 
    auto x1 = v[1]; 

    f(x0.get());    // After my imagination this would have called void f(const Int2Type<0>&) 
    f(x1.get());    // After my imagination this would have called void f(const Int2Type<1>&) 
} 

好了,我要選擇的f正確的過載,然而,這並不編譯在編譯時間,它是未知哪種類型x0x1實際上有。但是有沒有一些可以實現這種行爲的替代設計?

回答

0

重載是基於靜態類型的靜態機制。

如果你想基於對象的動態類型改變行爲動態,C++提供了另一種內置的語言特性爲:虛擬功能。他們使用像這樣的:

struct Int2TypeBase 
{ 
    virtual void do_f() = 0; 
}; 

template <int v> struct Int2Type : Int2TypeBase 
{ 
    void do_f() override 
    { 
     // specific behaviour for Int2Type<v> goes here 
    } 

    /* ... */ 
}; 

void f(Int2TypeBase & x) { x.do_f(); } 

現在,你可以在任何基子叫f和正確的行爲在運行時選擇。特別是,現在分別選擇f(x0.get())f(x1.get()),並分別在運行時分配到Int2Type<0>::do_fInt2Type<1>::do_f

+0

不幸的是不適用於我的情況,因爲實際上'f'函數有不同的返回類型。 –

+0

@lotolmencre:遺憾的是,您的問題是將這項新要求保密...... –

+0

是的,當我構建最小工作示例時,我沒有想到它。 –