2012-09-05 48 views
0

任何代碼,我有下面的類:模板時,沒有任何類型的共同點

class ValueSetter: public IValueSetter 
{ 
public: 
    explicit ValueSetter(CContainer* container) 
     : _container(container) 
    { 
    } 

    virtual void operator()(const int value, const int index) const 
    { 
     _container->values[index].value.i = value; 
    } 

    virtual void operator()(const double value, const int index) const 
    { 
     _container->values[index].value.d = value; 
    } 

    virtual void operator()(const std::string& value, const int index) const 
    { 
     ... 
     _container->values[index].value.s = _strdup(value.c_str()); 
    } 

private: 
    CContainer* _container; 
}; 

該類上CContainer存儲在工會的緩衝它的數據進行操作。我將ValueSetter傳遞給沒有CContainer知識的Container類。事實上,未來我希望CContainer(我通過C API獲得的)將消失,並且值被組織在std :: vector或std :: list中。我的容器的界面不需要因此而改變,不應該關心數據如何存儲在內存中。

考慮到這一點,我不是喜歡的東西大致沿着這些線路:

class IntValueSetter: public IIntValueSetter 
{ 
public: 
    explicit IntValueSetter(Container* container) 
     : _container(container) 
    { 
    } 

    virtual void operator()(const int value, const int index) const 
    { 
     _container->values[index].value.i = value; 
    } 
private: 
    CContainer_3* _container; 
} 

或:

class IntValueSetter: public IIntValueSetter 
{ 
public: 
    explicit IntValueSetter(std::vector<int> values) 
     : _values(values) 
    { 
    } 

    ... 
} 

但我需要能夠如下使用它們:

ValueSetter<int> valueSetter; 

,而不是

IntValueSetter valueSetter; 

我該怎麼做?

回答

4

只要做到明顯。沒有要求模板專業化與另一個專業化或原始模板有任何共同之處。所以:

class IIntValueSetter { 
}; 

template <class Ty> class ValueSetter; // declared but not defined 

template <> 
class ValueSetter<int> : public IIntValueSetter { 
    // whatever 
}; 

ValueSetter<int> vsi; 
+0

你會怎麼做,以避免一個IIntValueSetter接口,而不是使用IValueSetter 接口作爲基地 – Baz

+0

我不知道;你還沒有談過這件事。但正如你所建議的那樣,模板可能是正確的答案。 –

+0

我在這個問題中添加了自己的答案,其中顯示了接口的兩個實現。 – Baz

0

如果我得到你的權利,你只需要編寫一個類模板:

template <typename T> 
class ValueSetter 
{ 
public: 
    explicit ValueSetter(std::vector<T> values): _values(values) 
    { 
    } 
    virtual void operator()(const T value, const int index) const 
    { 
     _container->values[index].value.i = value; 
    } 
// etc. 
}; 
+0

沒有這個不會工作,因爲,例如,double存儲在d union成員中,而不是i(int)成員。 – Baz

+0

@巴茲 - 但這表明,容器的接口不夠豐富;如果可以增強它爲每個它可以處理的各種類型提供重載setter,那麼上面的代碼可以調用setter,並且重載解析會選擇合適的setter。 –

+0

@Pete Becker對不起,我沒有關注。你能說一點嗎?謝謝! – Baz

0

我想我在尋找這樣的事情。我只在下面實現了int,但每種類型都會得到它自己的接口類和實現類。我很想聽聽你對這種方法的評論!

template<typename V> 
class IValueSetter 
{ 
public: 
}; 

template<> 
class IValueSetter<std::string> 
{ 
public: 
    virtual void operator()(const std::string& value, int index) const = 0; 
}; 

template<typename V> 
class ValueSetter 
{ 
}; 

template<> 
class ValueSetter<std::string>: public IValueSetter<std::string> 
{ 
public: 
    explicit ValueSetter2(CContainer* container) 
     : _container(container) 
    { 
    } 

    void operator()(const std::string& value, int index) const 
    { 
     _container->values[index].value.s = _strdup(value.c_str()); 
    } 

private: 
    CContainer* _container; 
}; 

template<> 
class NewValueSetter<std::string>: public IValueSetter<std::string> 
{ 
public: 
    explicit NewValueSetter(std::shared_ptr<std::list<std::string>> values) 
     : _values(values) 
    { 
    } 

    void operator()(const std::string& value, int index) const 
    { 
     (*values)[index] = value; 
    } 

private: 
    std::shared_ptr<std::list<std::string>> _values; 
}; 
相關問題