簡體   English   中英

帶有std :: enable_if元函數的模板類中的重載運算符+ =

[英]Overload operator += in template class with std::enable_if metafunction

我有一個實現為類模板的字符串類,例如:

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標准。 目標是實現僅在模板的類T例如為“ wchar_t”時才使用的重載運算符+ =(const char)。

我想知道,如果編譯器不了解C ++ 11,我如何才能達到相同的結果。

更新:對不起,我是stackoverlow的新手,我還沒看到,我的代碼沒有在代碼塊中完全顯示。 到目前為止,我已經更新了我的代碼。 我還從模板函數運算符+ =()中更正了模板參數列表中的一個錯誤,您絕對正確的使用is_same<T, char>is_same<T, char>必須為is_same<U, char>

enable_if不依賴於C ++ 11功能。 在Boost庫中C ++ 11之前的實現方式幾乎與現在實現的方式相同。 這是來自cppreference.com的可能實現:

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

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

在C ++ 11之前的C ++中,這可以很好地工作。

首先,enable_if / is_same可以在C ++ 2003中輕松實現。 例如,Boost擁有它們,或者您可以自己創建這些-這是一個好習慣。

其次,如果您不想使用enable_if,則只需為w_char提供myString的特殊化。 為了減少編碼量,請將其放在某個基類中,從基類派生myString並提供基類的特殊化。

現在我已經弄清楚了,沒有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;
        }
};

首先,您的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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM