2016-02-18 13 views
6

Bir temel sınıf sağlamazsa, bir yöntemi doldurma hakkında nasıl giderdiniz? Sağlanmış ise temel sınıf yöntemini tekrar kullanmak istiyorum.Şablon tarafından sağlanan bir temel sınıfın uyarlanması

Örn:

#include <iostream> 
struct Base0 { }; 
struct Base1 { void m() { std::cout<<"Base1\n"; } }; 

template<typename T> 
struct Derived : public T { 
    //if T doesn't provide m, define it here, otherwise reuse the base class method 
    void m(){ /*? std::cout<<"Derived\n"; ?*/ } 
}; 

int main(){ 
    Derived<Base0> d0; 
    d0.m(); //should print "Derived" 
    Derived<Base1> d1; 
    d1.m(); //should print "Base1" 
} 
+0

Peki yapabilir Eğer gerçekten bu şekilde yapmak isterseniz, size çağrı ile ilgili bir sorun var yine de sipariş ver. Türetilmiş ve türetilmiş olduğu sürece türetilen bir fonksiyon 'm()' her zaman temel fonksiyonun üzerine yazacaktır 'm()' –

+0

Kavramları karıştırıyorsunuz: devralma, sanal fonksiyonlar ve şablonlar. Tamamen bir kod kokusu. Şablonlara sahip olmak, kalıtım ve sanal işlevlerden kaçınmak. –

cevap

8

SFINAE ile,

template<typename T> 
struct Derived : public T { 
private: 
    template <typename U = T> 
    auto m_impl(int) -> decltype(std::declval<U&>().m()){ this->U::m(); } 

    template <typename U = T> 
    void m_impl(...) { std::cout<<"Derived\n"; } 

public: 
    void m() { m_impl(0); } 
}; 

Demo

2

, farklı bir imza altına zaten işlevini tanımlamak gerekir genel olmak amacıyla:

template<typename T> 
struct Derived : public T 
{ 
    auto m(std::false_type) { std::cout<<"Derived\n"; } 
}; 

Sonra kontrol etmek için this thread verilen yöntemleri kullanabilirsiniz temel sınıfın, m(): numaralı işlevi olup olmadığıSon olarak, zaten söyledi Aslay Berby olarak

0

template<typename T> 
struct Derived : public T 
{ 
    auto m(std::true_type) { return T::m(); } 
    auto m(std::false_type) { std::cout<<"Derived\n"; } 
    auto m() { return m(detect</* const */ T, has_m>{}); } 
           ^^^^^^^^^^ 
           //if m() is const 
}; 

olarak bu muhtemelen gitmek istiyorsunuz yol olmadığını kullanabilirsiniz. Özellikler veya politika tabanlı tasarım gibi bir şey uygulamak istiyorsanız, aşağıdaki kod aradığınız şey olabilir. Aslında bu tür tasarımlar oldukça yaygın olarak kullanılır ve aynı zamanda deyimsel değere sahiptir.

#include <iostream> 
using namespace std; 

struct StandardTraits {void foo() {cout << "standard" << endl;}}; 

struct Traits1 {void foo() {cout << "traits1" << endl;}}; 
struct Traits2 {void foo() {cout << "traits2"<< endl;}}; 

template<typename T = StandardTraits> 
class SomeClass 
{ 
public: 
    typedef T Traits; 

    void useTraits() {traits.foo();} 

private: 
    Traits traits; 
}; 

int main() { 

    SomeClass<> x; 
    SomeClass<Traits1> y; 
    SomeClass<Traits2> z; 

    x.useTraits(); 
    y.useTraits(); 
    z.useTraits(); 

    return 0; 
} 

// output: 
// standard 
// traits1 
// traits2 

Ayrıca bakınız: https://en.wikipedia.org/wiki/Policy-based_design

İlgili konular