非模板类的模板化构造

时间:2011-09-13 16:40:57

标签: c++ templates constructor specialization

我有一个具有共同成员的类,但需要基于枚举以有限的方式构造。每种类型在编译时都是已知的,所以我认为模板在这里有意义。我知道我可以用构造函数特化来解决这个问题,例如:

enum SensorTypes{GPS,Radar,ShaftEncoder};

template<SensorTypes>
class Sensor
{
public:
    Sensor(unsigned char* rawdata){//Format of rawdata depends on SensorTypes};
private:
    double speed;
    double time;
}
template<> Sensor<GPS>::Sensor(unsigned char* rawdata){speed = (double)rawdata[0];}

问题是我有遗留代码必须接受Sensor类而不是Sensor<GPS>等。如何在保持单个类类型的同时实现类似的编译时间构造。

3 个答案:

答案 0 :(得分:2)

一开始看起来很简单,只需在Sensor类中使用模板化构造函数。

#include <stdio.h>

namespace sensorKind {
    struct GPS {};
    struct Radar {};
    struct ShaftEncoder {};
}

class Sensor
{
public:
    template< class Kind >
    Sensor( Kind, unsigned char const* rawdata );
private:
    double speed_;
    double time_;
};

template<>
Sensor::Sensor(
    sensorKind::GPS,
    unsigned char const* rawData
    )
{
    printf( "Sensor<GPS> object created.\n" );
}

template<>
Sensor::Sensor(
    sensorKind::Radar,
    unsigned char const* rawData
    )
{
    printf( "Sensor<Radar> object created.\n" );
}

int main()
{
    Sensor  aGPSSensor( sensorKind::GPS(), 0 );
    Sensor  aRadarSensor( sensorKind::Radar(), 0 );
}

但是在这一点上很容易看出“类型参数”真的是在描述rawdata,而不是别的。

所以,它应该是应该输入的rawdata参数。

使rawdata更加严格打字也可以帮助你避免犯规雷达rawdata被视为GPS rawdata。

#include <stdio.h>

namespace sensor {
    struct Kind {
        enum  Enum{ gps, radar, shaftEncoder };
    };

    template< Kind::Enum aKind >
    class DataFrom 
    {
    public:
        static Kind::Enum const kind = aKind;

        unsigned char const* ptr() const { return 0; }
        DataFrom() {}
    };
}  // namespace sensor

class Sensor
{
public:
    typedef sensor::Kind    Kind;

    template< class DataKind >
    explicit Sensor(  DataKind const& rawData );
private:
    double speed_;
    double time_;
};

template<>
Sensor::Sensor( sensor::DataFrom< Kind::gps > const& rawData )
{
    printf( "%s\n", "Sensor<GPS> object created." );
}

template<>
Sensor::Sensor( sensor::DataFrom< Kind::radar > const& rawData )
{
    printf( "%s\n", "Sensor<Radar> object created." );
}

int main()
{
    sensor::DataFrom< sensor::Kind::gps >   gpsData;
    sensor::DataFrom< sensor::Kind::radar > radarData;

    Sensor  aGPSSensor( gpsData );
    Sensor  aRadarSensor( radarData );
}

设计方面,这是分区为rawdata提供程序和rawdata解释器(Sensor类显然是一个rawdata解释器。)

这个设计是由问题暗示的,但如果可能那么将解释知识更接近数据源可能是有益的。

即,移动对例如雷达数据来自Sensor构造函数和类,以及携带雷达原始数据的类。

干杯&amp;第h。,

答案 1 :(得分:0)

根据您的特定需求,您可以创建非模板基类并派生特定于模板的版本,使用虚拟方法选择正确的行为。

答案 2 :(得分:0)

这看起来很简单,只需让您的模板类派生自现有的Sensor类。

template<SensorTypes>
class DerivedSensor : public Sensor
{
public:
    DerivedSensor(unsigned char* rawdata){//Format of rawdata depends on SensorTypes};
};