2014-01-07 66 views
6

看看這段代碼。將std :: vector重命名爲另一個類以用於重載?

#include <vector> 

template<class ...Args> 
using other_vector = std::vector<Args...>; 

template<class T> 
void f(std::vector<T>&) {} 
template<class T> 
void f(other_vector<T>&) {} 

int main() 
{ 
    other_vector<int> b; 
    f(b); 
    return 0; 
} 

它不會編譯,因爲f被重新聲明。我完全理解錯誤。但是,我需要第二個類,其行爲類似於std::vector<T>,但會被視爲不同的類型,所以像上面的示例一樣,重載將是合法的。

我該怎麼辦?

  • 讓新班級有std::vector<T>作爲基類。這可能工作,但不應該從std容器繼承。
  • 讓新類具有std :: vector類型的成員,然後重新聲明所有函數以重定向到成員函數。聽起來很多工作。

有什麼更好的選擇? C++ 11或C++ 14允許。

+6

看看'BOOST_STRONG_TYPEDEF'。如果它不能與模板一起工作,那麼你可以借鑑靈感來做出一些事情。 – chris

+1

你確定你需要兩個幾乎相同類型的函數嗎? – StoryTeller

+0

嘗試繼承。 –

回答

17

您可以嘗試亂用分配器:

template<class T> 
struct allocator_wrapper : T { using T::T; }; 

template<class T, class A = std::allocator<T>> 
using other_vector = std::vector<T, allocator_wrapper<A>>; 

Live example

+0

聰明的主意......謝謝,這有效。 – Johannes

+0

'using T :: T;'Whoa OO +1 – StoryTeller

+1

@Johannes如果你需要更多這些不同的類型,只需要在'allocator_wrapper'中添加一個整型參數,你就可以有任意數量的... :) –

0

如果你需要一個以上的副本,你可以把它的模板,並採取int模板ARG爲「克隆號」

+0

但是我仍然需要使用上面提到的兩點之一,並提到缺點? – Johannes

+0

@Johannes確實如此,但您可以將「int」模板參數與針對1個克隆的任何解決方案相結合,將其擴展爲N –

0

,你可以換你喜歡的類型如下:

// N allow to have several 'version' of the same type T 
template <typename T, int N = 0> 
class WrapperType 
{ 
public: 
    WrapperType() = default; 
    WrapperType(const WrapperType&) = default; 
    WrapperType(WrapperType&&) = default; 

    template <typename ... Ts> 
    explicit WrapperType(Ts&& ... ts) : t(std::forward<Ts>(ts)...) {} 

    // implicit conversion 
    // you may prefer make them explicit or use name get(). 
    operator const T&() const { return t; } 
    operator T&() { return t; } 

private: 
    T t; 
}; 

等你的情況:

template<class T> 
using other_vector = WrapperType<std::vector<T>>;