【问题标题】:Implement specific method in generic class在泛型类中实现特定方法
【发布时间】:2018-11-17 18:44:43
【问题描述】:

我有一个问题,在互联网上搜索了一段时间,但没有任何好的结果。

我有一个用于 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 ); 
    }
...
};

当我实例化该泛型类时,它使我能够为图片的像素选择特定类型,例如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!

我怎么能做我想做的事?

【问题讨论】:

  • 我建议将 sepiaFilter 编写为独立的函数模板,而不是成员。然后,您可以轻松地在特定情况下重载它。
  • 我不清楚您想专门研究Image2D&lt;TValue&gt;::sepiaFilter&lt;Color&gt;(Image2D) 的哪些案例。当TValueColor 是同一类型时?当其中一个或两个是unsigned char?
  • 另外,您的sepiaFilter 函数似乎没有使用this。所以也许它不应该有一个单独的Image2D 参数,或者它应该是static,或者它应该是一个非成员,如 n.m.建议?

标签: c++ templates generics types template-specialization


【解决方案1】:

如果我正确理解了您的问题,那么您可以采取一些方法。我认为您想要的是模板专业化。为此,您需要修改泛型类以包含您想要专门化的功能:

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&lt;Color&gt; 现在有专门定义的行为。

另外,这不是您的问题的一部分,而是您对该功能的足迹的明智之举。我建议改为使用

//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

在这种情况下,您可能希望修改它自己的成员而不是传递的成员

无论如何,我希望这能回答你的问题,祝你好运!

【讨论】:

    【解决方案2】:

    谢谢大家的帮助! Bronicki 的解决方案正在奏效。 在按照他所说的使用

    void sepiaFilter() { ... }
    

    是一个很好的解决方案。

    我叫它

    img.sepiaFilter();
    

    在 main 方法中,img 是一个 Image2D 实例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多