2011-02-26 131 views
5

我有一个类tPoint,将具有不同碱基类型来实现,以便特定模板重载成员函数专业化

template<typename T>class tPoint{ 
    T x; 
    T y; 
public: 
    void Set(T ix, T iy){x=ix;y=iy;} 
}; 

当类型T为int,tPoint<int>,我想一组特殊的(浮动,浮动),所以我可以在分配前将值舍入。

我认为专业化我可以:

template<> void tPoint<int>::Set(float ix,float iy){x=ix+.5; y=iy+.5;} 

这样编译器抱怨有在类定义中没有匹配的功能。

但是,如果我在班上设置声明(浮动,浮动),那么它说,这已经定义(当它编译为T =浮动)

我希望我自己清楚,这将是一个干净的方法这或我做错了什么?谢谢!

回答

5

您需要专门的类,像这样:

template<> class tPoint<int>{ 
    int x; 
    int y; 
public: 
    void Set(int ix, int iy){x=ix;y=iy;} 
    void Set(float ix, float iy){x = ix+0.5; y = iy+0.5;} 
}; 
+0

我会专门浮动版本而不是所有的非浮动的一个:-) – AProgrammer 2011-02-26 17:55:40

+0

@AProgrammer,在OP只提到希望专注于tPoint ,但我同意他是否想要第二个“设置”多于一个班。 – 2011-02-26 18:05:57

0

使用升压enable_if防止浮版本时使用float实例化。

0

你最好的选择是:

template<typename T>class tPoint{ 
    T x; 
    T y; 
public: 
    void Set(T ix, T iy) { set_impl(boost::type<T>(), x, y); } 
private: 
    void set_impl(boost::type<int>, float ...); 
    template<typename U> 
    void set_impl(boost::type<U>, T ...); 
}; 
0

尽量不提供设置的默认实现()里面的类。这样,专注于浮动更容易。

3

您面临的问题与T有关,可能是intfloat

如果你看一下模板类的定义,你会此话是那typename后出现在template部分相同T也表现为参数的Set方法。

这意味着,当你说话的Point<int>那么只有一个Set定义的方法,它有两个int。而且每个不同的Point<T>都会有自己的Set(T,T)方法。

如果你希望有一个不同的Set方法,那么你需要的模板类中声明模板Set,这样做是像这样:

template <typename T> 
class Point 
{ 
public: 
    template <typename Num> 
    void Set(Num x, Num y); 
}; 

注意我如何不得不选择了不同的模板参数名称。


为了解决你的问题,你可以介绍另一种方法,float,但你得有另一为double,并long double ...它很快会变得困难。

最简单的办法,就是去暴力破解:

template <typename Integral> 
template <typename Num> 
void Point<Integral>::Set(Num x, Num y) 
{ 
    this->x = long double(x) + 0.5; 
    this->y = long double(y) + 0.5; 
} 

对于int和人,它主要是无用的,但工程。对于浮点,我们使用更大的浮点类型以避免丢失精度,然后执行舍入。

显然,如果我们突然想要一个Point<float>,那就不太合适,因此我们需要一个基于类型特征的更智能的解决方案。类std::numeric_limits<T>有一个is_integer,它降低了我们是否正在处理整数类型。

template <typename T> 
template <typename Num> 
void Point<T>::Set(Num x, Num y) 
{ 
    if (std::numeric_limits<T>::is_integer && 
    !std::numeric_limits<Num>::is_integer) 
    { 
    this->x = x + 0.5; 
    this->y = y + 0.5; 
    } 
    else 
    { 
    this->x = x; 
    this->y = y; 
    } 
    } 
} 

我知道这似乎愚蠢使用的东西,可以在编译时确定的if ......不过不用担心,编译器是足够聪明,数字出来编译期时时间和优化掉if和未使用的分支完全;)

+0

谢谢,它比我期望的要复杂得多,但是你的帖子在模板专业化方面有一些新手点 – Joan 2011-02-26 19:46:22