簡體   English   中英

在泛型類中實現特定的方法

[英]Implement specific method in generic class

我有一個問題,在互聯網上搜索了一段時間,但結果還是不好。

我有一個用於2D圖片的通用類Image2D

template <typename TValue>
class Image2D 
{
    public:
    typedef Image2D<TValue>    Self;      // le type de *this
    typedef TValue             Value;     // le type pour la valeur des pixels
    typedef std::vector<Value> Container; // le type pour stocker les valeurs des pixels de l'image.

    Image2D( int w, int h, Value g = Value() )
        : m_width(w), m_height(h), m_data(Container(w * h, g)) { }

    struct Iterator : public Container::iterator 
    {
        Iterator( Self & image, int x, int y ) 
        : Container::iterator( image.m_data.begin() + image.index( x, y ) ) { }
    };
    Iterator begin() 
    { 
        return start( 0, 0 );
    }
    Iterator end()   
    { 
        return start( 0, h() ); 
    }
    Iterator start( int x, int y ) 
    { 
        return Iterator( *this, x, y ); 
    }
...
};

實例化泛型類時Color(unsigned char, unsigned char, unsigned char)它使我能夠為圖片的像素選擇特定的類型,例如unsigned charColor(unsigned char, unsigned char, unsigned char)

我需要為該類添加一個方法,其中某些類型的實現可能有所不同:

template <typename TValue>
class Image2D
{
...

    template <typename Color>
    void sepiaFilter()
    {
        for(Iterator it = this -> begin(), itE = this -> end(); it != itE; ++it)
        {
            Color oldColor = *it;

            Color newColor = oldColor;

            newColor.red = std::min((oldColor.red * .393) + (oldColor.green * .769) + (oldColor.blue * .189), 255.0);
            newColor.green = std::min((oldColor.red * .349) + (oldColor.green * .686) + (oldColor.blue * .168), 255.0);
            newColor.blue = std::min((oldColor.red * .272) + (oldColor.green * .534) + (oldColor.blue * .131), 255.0);

            *it = newColor;
        }
    }
...
};

相同的方法適用於unsigned char ,但方法的核心不應相同。

問題是我不知道如何針對特定類型專門化泛型函數。 我試圖創建這個:

template<>
class Image2D<Color> 
{
    template <typename Color>
    void sepiaFilter()
    {
        for(Iterator it = this -> begin(), itE = this -> end(); it != itE; ++it)
        {
            Color oldColor = *it;

            Color newColor = oldColor;

            newColor.red = std::min((oldColor.red * .393) + (oldColor.green * .769) + (oldColor.blue * .189), 255.0);
            newColor.green = std::min((oldColor.red * .349) + (oldColor.green * .686) + (oldColor.blue * .168), 255.0);
            newColor.blue = std::min((oldColor.red * .272) + (oldColor.green * .534) + (oldColor.blue * .131), 255.0);

            *it = newColor;
        }
    }
}

並創建另一個特定的Image2D類。 但是,這樣做需要在該專用類中重新實現迭代器。 所以我不能使用通用類的迭代器。

因此這些解決方案均無效,因此我需要幫助.. Heeeeelp!

我該怎么辦?

如果我正確理解了您的問題,那么您可以采取幾種方法。 我認為您想要的是模板專業化。 為此,您想要修改泛型類以包括要專門化的功能:

template <typename TValue>
class Image2D{
    //your original code here
    void sepiaFilter(Image2D<Value> img){}
};

請注意,我沒有給函數一個主體。 現在它什么也沒做。 現在我們專門研究該功能:

template<>
void Image2D<Color>::sepiaFilter(Image2D<Color> img){
    //body of your function here
}

就是這樣! Image2D<Color>現在具有特別定義的行為。

同樣,這也不是您的問題的一部分,而是您對該功能的明智之舉。 我建議改用

//code before function definition
static void sepiaFilter(Image2D<Value>& img){
    //modify member values of img by reference
}
//code after function definition

添加static的原因是該函數不會修改其自己對象的成員值。 並且&符使它通過引用傳遞,否則完成后對img所做的任何更改都將消失。 或者,您可以這樣做:

//code before function definition
void sepiaFilter(){
    //modify member values of this
}
//code after function definition

在這種情況下,您將需要修改自己的成員,而不是修改已通過的內容

無論如何,我希望這能回答您的問題,祝您好運!

謝謝你們的幫助! Bronicki的解決方案正在工作。 做完他所說的使用后

void sepiaFilter() { ... }

是一個很好的解決方案。

我打電話給

img.sepiaFilter();

在main方法中,img是Image2D實例。

暫無
暫無

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

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