2015-10-16 51 views
1

模板類我有一個字符串類實現爲像類模板:過載操作者+ =與標準:: enable_if元函數

template <class T> 
class HGStringBasic 
{ 
//... 
public: 
//... 
    HGStringBasic& operator += (const T* rhs) 
    { 
     //... 
    } 

    template <class U, std::enable_if_t<std::is_same<U, char>::value>* = nullptr> 
    HGStringBasic& operator += (const U* rhs) 
    { 
     //... 
    } 
//... 
} 

該代碼是C++ 11標準一致。 目標是實現重載操作符+ =(const char),僅當模板的類T爲「wchar_t」時才使用它。

我想知道,如果編譯器不理解C++ 11,我該如何實現相同的結果。

更新: Sry我是新來的stackoverlow,我還沒有看到,我的代碼沒有完全顯示在代碼塊中。現在我已經更新了我的代碼了。 我也更正了模板函數操作符+ =()中的模板參數列表中的一個錯誤,您絕對是正確的TartanLlama,is_same<T, char>必須是is_same<U, char>

+1

這是否'的std :: enable_if'甚至工作?我認爲失敗會很困難,因爲'T'不在函數聲明的直接上下文中。 – TartanLlama

+0

你是絕對正確的,is_same 必須is_same 在這種情況下 – Christian

回答

0

現在我已經想通了,沒有C++ 11和已知的元函數。非常感謝Barry提供指定返回類型的提示。

這裏是我做的:

#include <type_traits> 

template <class _ElemT> 
class HGStringBasic 
{ 
    public: 
     // Append char* or wchar_t* depending on specialization 
     HGStringBasic& operator += (const _ElemT* rhs) 
     { 
      return *this; 
     } 

     // Allow char* if specialization is wchar_t 
     template <class U> 
     typename std::enable_if<std::is_same<U, char>::value, HGStringBasic&>::type operator += (const U* rhs) 
     { 
      // Convert ansistring to widestring 
      return *this; 
     } 

     // Allow wchar_t* if specialization is char 
     template <class U> 
     typename std::enable_if<std::is_same<U, wchar_t>::value, HGStringBasic&>::type operator += (const U* rhs) 
     { 
      // Convert widestring to ansistring 
      return *this; 
     } 
}; 
1

enable_if不依賴於C++ 11的功能。它在C++ 11之前在boost庫中的實現方式幾乎與現在實現的方式相同。下面是從cppreference.com採取可能的實現:

template<bool B, class T = void> 
struct enable_if {}; 

template<class T> 
struct enable_if<true, T> { typedef T type; }; 

這完全正常工作在C++之前,C++ 11。

1

首先,enable_if/is_same可以很容易地在C++ 2003中實現。舉例來說,Boost擁有它們,或者你可以創建那些你自己的 - 這是一個很好的做法。其次,如果你不想使用enable_if,你可以簡單地爲w_char提供myString的專門化。爲了減少編碼量,把它放在一些基類中,從基類派生myString並提供基類的專門化。

0

首先,你的C++ 11確實不是的工作。如果我試圖做的:

myString<int> x; 
x += new int(4); 

operator+=會出錯。 SFINAE只適用於直接上下文的替換 - 但T並不在此處,而只有U。所以,正確的事情是:

template <class U, 
      class _T=T, 
      class = std::enable_if_t<std::is_same<_T, char>::value>> 
myString& operator += (const U* rhs); 

現在回到原來的問題。我們如何在C++ 03中編寫上述代碼?同樣的想法。我們不能擁有默認的模板參數。但是,同樣的原則也適用:我們需要在直接背景替換故障:

template <typename T, typename U, typename R> 
struct allow_for_char; 

template <typename U, typename R> 
struct allow_for_char<char, U, R> { typedef R type; }; 

然後你可以用它來指定返回類型:

template <class U> 
typename allow_for_char<T, U, myString&>::type 
operator += (const U* rhs); 
+0

你是對的,它不會工作。我現在更新了我的代碼... – Christian

+0

@Christian等一下,那是一個*完全*不同的問題。現在你甚至不需要'enable_if' ... – Barry

+0

我需要'enable_if_t <>'如果專精是例如'HGStringBasic ',那麼我有一個'operator + =(const wchar_t *)',第二個運算符是'operator + =(const char *)'。但是如果專門化是HGStringBasic ,第二個運算符將不會被使用,因爲'operator + =(const char *)'的第一個實現。因此,如果專門化爲'',我可以將'const char * HGStringBasic '。 – Christian