是否可以推断模板模板参数参数(没有错字:-))

Is it possible to deduce template template parameter parameter (no typo :-) )

我有一个 class 实现了一个大型项目的数据类型。我这里简化为(实际上是subclass传递typeID和subTypeID给iots父class构造函数):

template<typename T,uint32_t typeID, uint32_t subTypeID> class TDataType {
  private:
    T _value;
};

请注意,在这种情况下,使用类似于变体的东西不是一种选择。还需要类型 ID,这与 OO 无关,但与软件配置有关。我确实将它们包含在这个 simpel 示例中只是为了显示完整的模板参数。

我想要实现的是实现一个转换模板,它能够透明地从一种简单类型转换为另一种(对于某些类型(如 std::string)我知道我需要一个专门的模板。

所以我想要这样的东西(伪语法)来将 T1 转换为 T2 都是某种 TDataType classes:

template<class TDataType<typename T1,uint32_t TYP1, uint32_t STYP1>,
         class TDataType<typename T2,uint32_t TYP2, uint32_t STYP2>> convert(TDataType<T1,TYP1,STYP1> &v1, 
        TDataType<T2,TYP2,STYP2> &v2)
          { v1._value = static_cast<T1>(v2._value); }

其中 T1/2、TYP1/2 和 STYP1/2 将从传递的 TDataType

推导出来

例如,可以执行以下操作:

TDataType<int32_t,1,32> Int{3};
TDataType<double,2,2> Double;

convert(Int,Double); // Set Double to 3.0

请注意,thios 转换只是用例的一个示例,例如还有更多类似的运算符。所以我主要看这个模板-模板-参数-参数推导是否可以。

另一个示例类似于:

template<class TDataType<typename T,uint32_t TYP, uint32_t STYP>,
         typename LT> 
    operator=(LT &lh,TDataType<T,TYP,STYP> &rh) 
      { lh = static_cast<LT>(rh._value); }

将 TDataType 简单分配给另一个 TDataType 不是问题,因为这可以在目标 class 模板内部实现,并使用 static_cast 的“本地”模板类型参数。

当然有可能,正确的语法很简单:

template<typename T1, uint32_t TYP1, uint32_t STYP1,
         typename T2, uint32_t TYP2, uint32_t STYP2>
void convert(TDataType<T1, TYP1, STYP1> from, TDataType<T2, TYP2, STYP2> &to)
{
    to = static_cast<T2>(from.value()); // assuming TDataType has a ctor TDataType(T)
}

但是创建一个直接从另一个 TDataType 实例初始化的模板化转换构造函数可能更好:

template<typename T, uint32_t typeID, uint32_t subTypeID>
class TDataType {
    T _value;
public:
    TDataType(T value) : _value(value) {}

    template<typename P, uint32_t pTypeID, uint32_t pSubTypeID>
    TDataType(TDataType<P, pTypeID, pSubTypeID> that) : _value(static_cast<T>(that._value)) {}

    template<typename, uint32_t, uint32_t>
    friend class TDataType; // to be able to access that._value
};

或者,使用用户定义的转换运算符使不同的 TDataType 相互转换。

template<typename T, uint32_t typeID, uint32_t subTypeID>
class TDataType {
    T _value;
public:
    TDataType(T value) : _value(value) {}

    template<typename P, uint32_t pTypeID, uint32_t pSubTypeID>
    operator TDataType<P, pTypeID, pSubTypeID>() const {
        return static_cast<P>(_value);
    }
};

您可以进一步专门化转换运算符,以根据目标类型执行不同的操作and/or声明默认特化已删除,以便更好地控制允许哪些转换。

那么你将能够做到:

TDataType<int32_t, 1, 32> Int{ 3 };
TDataType<double, 2, 2> Double = Int;