Specialize Many Templates for a Set of Types

旧城冷巷雨未停 提交于 2019-12-04 18:22:34

Condensing this down to a smaller example, based on the discussion in the comments on the question, you have a type Matrix<T> and you wish to implement, say, operator+=. The behaviour of this operator differs depending on whether the operand is a scalar or another matrix.

You therefore want to provide two specialisations; one for matrix-scalar operations, and one for matrix-matrix operations. Within those, you want to accept any valid scalar type, or any valid matrix type.

This is a classic use case for type traits and SFINAE using std::enable_if. Define a trait is_scalar:

// Base template:
template <typename T>
struct is_scalar : std::false_type {};

// Specialisations for supported scalar types:
template <> struct is_scalar<int> : std::true_type {};
template <> struct is_scalar<float> : std::true_type {};
template <> struct is_scalar<double> : std::true_type {};
// etc.

And a trait is_matrix:

// Base template:
template <typename T>
struct is_matrix : std::false_type {};

// Specialisations:
template<typename T>
struct is_matrix<Matrix<T>> : std::true_type {};
// and possibly others...

Your operators will then be (member) function templates of the form:

template <typename T>
std::enable_if_t<is_scalar<T>::value, Matrix&> operator+=(const T& rhs) {
  // Implementation for addition of scalar to matrix
}

template <typename T>
std::enable_if_t<is_matrix<T>::value, Matrix&> operator+=(const T& rhs) {
  // Implementation for addition of matrix to matrix
}

Note that is_scalar is already provided for you by the standard library! All this leaves is for you to define is_matrix specialisations for any matrix types you support.

If you're trying to implement this template only for certain types you can declare them in a .cpp file, similar to this: Why can templates only be implemented in the header file?

If you want to allow anything to be in this template, but explicitly declare certain types, this link might be helpful: http://en.cppreference.com/w/cpp/language/template_specialization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!