上下文
我们正在尝试设置一个名为Operand的类模板,它可以将几种类型作为其类型名T
。这些在以下枚举中定义:
enum eOperandType {
INT8
INT16,
INT32,
FLOAT,
DOUBLE
};
那些对应于<cstdint>
中定义的类型,即int8_t, int16_t
,等等。
构造函数必须为Operand(std::string const & value);
。
template<class T>
class Operand : public IOperand
{
public:
Operand(std::string const & value)
{
std::stringstream ss(value);
ss >> _value;
//_type = ??? ;
}
[...]
private:
Operand(void){}
eOperandType _type;
T _value;
};
接口IOperand在这里并不重要,只是运算符重载的一些原型。
问题:
设置_type
属性的最佳方法是什么?简单的方法是用if/else if
写一些typeid
或接近它的东西,但我觉得那会很脏。此外,我只是认为在模板中使用typeid
只是意味着你在某处做错了什么......对吗?
答案 0 :(得分:5)
使用帮助程序类推导出_type
的值。
template <typename T> struct OperandType;
template <> struct OperandType<int8_t>
{
static const eOperandType t = INT8;
};
template <> struct OperandType<int16_t>
{
static const eOperandType t = INT16;
};
等
并将其用作:
Operand(std::string const & value) : type_(OperandType<T>::t)
{
...
}
<强> PS 强>
鉴于您可以在需要时随时推断type_
的值,将它存储为成员变量是否有意义?
答案 1 :(得分:4)
您可以使用模板重载。如果您为每种类型专门化模板参数,则可以设置特定参数,您可以在专用模板中具有特定值。然后,您可以将该值用于_type
属性。所以,如果你做这样的事情
template<typename _Ty> struct OperandSelector;
template<> struct OperandSelector<int8_t> {
static const eOperandType value = INT8;
}
然后为您要使用的每个值创建另一个专门化,例如INT16
,INT32
,FLOAT
和DOUBLE
。要设置_type
的值,您可以使用OperandSelector<T>::value
这样的值为其分配
_type = OperandSelector<T>::value;
这种方法允许在编译时完成选择,并选择值作为简单副本。
答案 2 :(得分:0)
template<class...>struct types{using type=types;};
template<class E, E...es>
using enums=std::integer_sequence<E,es...>;
template<class types, class T, class enums>
struct pick;
template<class T0, class...Ts, class T, class E, E e0, E...es>
struct pick< types<T0, Ts...>, T, enums<E,e0,es...>>:
pick< types<Ts...>, T, enums<E,es...>>
{};
template<class T0, class...Ts, class E, E e0, E...es>
struct pick< types<T0, Ts...>, T0, enums<E,e0,es...>>:
std::integral_constant<E,e0>
{};
然后
using c_types = types<int8_t, int16_t, int32_t, float, double>;
using e_types = enums<eOperandType, INT8, INT16, INT32, FLOAT, DOUBLE>;
并且在班级本身:
static const eOperandType _type = pick<c_types, T, e_types>::value;
这不会与许多类型的人合作。
我在这里制作了static const
,因为它不能改变,为什么要这样呢?