在通用 class 中实现特定方法
Implement specific method in generic class
我有一个问题,在网上搜索了一段时间,但没有什么好的结果。
我有一张通用的 class 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 char
或 Color(unsigned char, unsigned char, unsigned char)
当我实例化通用 class.
我需要向那个 class 添加一个方法,其中某些类型的实现可能有所不同:
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;
}
}
}
并创建另一个特定的 class Image2D。但是这样做需要迭代器必须在那个专门的 class 中重新实现;所以我不能使用通用的 class' 迭代器。
所以 none 这些解决方案有效,所以我正在寻求帮助.. Heeeeeelp!
我怎么能做我想做的事?
如果我对你的问题的理解正确,那么你可以采取一些途径。我认为您想要的是模板专业化。为此,您要修改泛型 class 以包含您要专门化的函数:
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实例。
我有一个问题,在网上搜索了一段时间,但没有什么好的结果。
我有一张通用的 class 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 char
或 Color(unsigned char, unsigned char, unsigned char)
当我实例化通用 class.
我需要向那个 class 添加一个方法,其中某些类型的实现可能有所不同:
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;
}
}
}
并创建另一个特定的 class Image2D。但是这样做需要迭代器必须在那个专门的 class 中重新实现;所以我不能使用通用的 class' 迭代器。
所以 none 这些解决方案有效,所以我正在寻求帮助.. Heeeeeelp!
我怎么能做我想做的事?
如果我对你的问题的理解正确,那么你可以采取一些途径。我认为您想要的是模板专业化。为此,您要修改泛型 class 以包含您要专门化的函数:
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实例。