仅为具有运算符/已定义</t>的T创建模板<t>

时间:2014-12-22 17:16:58

标签: c++ templates operators

我想为类型定义template<T>,但我必须确保仅定义operator/operator+的类型可以作为{{1}传递}} 即可。

这是因为我希望能够获得其中两个(具有相同类型)的插值,例如:

T

对于template<class T> class Key final : public KeyBase{ public: //to keep the example simple //unsigned timeMS; <-- iherited from KeyBase T value; public: Key(unsigned timeMS, const T &value) : KeyBase(timeMS), value(value){} T inline getValue(){ return value; } }; Key<float> start = {10, 5.0f}; Key<float> end = {15, 3.0f}; float ratioAtTime12 = 12 / (end.timeMS - start.timeMS); float valueAtTime12 = start.value + (end.value - start.value) * ratio; //Point2D is my own custom type that have operator+, - and / defined Key<Point2D> start2 = {10, Point2D(10, 15)}; Key<Point2D> end2 = {15, Point2D(111, 6)}; ... Key<Character> start3 = {10, Character("Alan")}; //SHOULD generate an error //because my custom Character type has no operator+, - or / defined! float等简单类型,可以。但是,如果他们没有intT定义,如何防止将复杂类型用作operator/

1 个答案:

答案 0 :(得分:6)

如果您想要一个不包含通过ADL等找到的数十个运算符的错误消息,您可以定义特征:

template <typename, typename=void>
struct isAddable : std::false_type {};

template <typename T>
struct isAddable<T, decltype(void(std::declval<T>() + std::declval<T>()))>
    : std::true_type {};

template <typename, typename=void>
struct isDividable : std::false_type {};

template <typename T>
struct isDividable<T, decltype(void(std::declval<T>() / std::declval<T>()))>
    : std::true_type {};

...并使用静态断言。

static_assert( isAddable<T>{} && isDividable<T>{}, "Invalid T!" );

或者,要获得更具体的信息:

static_assert( isAddable<T>{}, "T not addable!" );
static_assert( isDividable<T>{}, "T not dividable!" );

Demo


您还可以使用方便的宏来定义此类特征。

#define VAL std::declval<T>()

#define DEF_TRAIT(name, expression)                                  \
template <typename, typename=void> struct name : std::false_type {}; \
template <typename T>                                                \
struct name<T, decltype(void(expression))> : std::true_type {};

DEF_TRAIT(isDividable, VAL / VAL)
DEF_TRAIT(isAddable, VAL + VAL)

Demo