Search code examples
c++templatesc++14type-deduction

Deduce type of a member of a template argument object


Having this function:

template <typename T>
T operator-(const T vector)
{}

I want to enforce that T has x and y members, and that they are arithmetic. I was trying to do it via std::declval<T>:

template <typename T,
  typename = typename 
    std::enable_if<std::is_arithmetic<std::declval<T>.x>::value>::type,
  typename = typename 
    std::enable_if<std::is_arithmetic<std::declval<T>.y>::value>::type>
T operator-(const T vector)
{}

But all I get is, that the type cannot be deduced: error: insufficient contextual information to determine type. Can the type of a member of template parameter object be deduced at all?


Solution

  • I take it that you don't actually want to enforce that they're arithmetic. You want that the crucial expressions in the function template's body are well-formed. In that case, go for something along the lines of

    template <typename T>
    auto operator-(const T& vector)
      -> decltype(void(x - vector.x), void(y - vector.y), vector)
    {/* ... */}
    

    If you'd rather stick to a correct version of your code, substituting decltype(std::declval<T>().x) or decltype(T::x) for std::declval<T>.x (ditto for y) is sufficient:

    template <typename T,
      typename = std::enable_if_t<std::is_arithmetic<decltype(T::x)>{}>,
      typename = std::enable_if_t<std::is_arithmetic<decltype(T::x)>{}>>
    T operator-(const T vector)
    {}