Home > OS >  C Metaprogramming sum of two types
C Metaprogramming sum of two types

Time:08-03

I have a class like this

template <typename T>
class Matrix {
typedef T value_type
...
};

I would like to write a function that needs to deal with different Matrix<T> types but also with arithmetic types (that is why I cannot use Matrix<T1> and Matrix<T2> as template arguments). Inside the function I need a Matrix that has the correct type, if I pass Matrix<T3> and Matrix<T4> for a and b then the type of the Matrix C should be whatever T3 T4 returns (T3 and T4 are arithmetic types).

template <typename T1, typename T2>
auto add(T1&& a, T2&& b);
Matrix<decltype(a(0,0)   b(0,0))> C{}; // This works, but I am sure there is a nicer solution

I found one way to do it but I am sure that it is possible to work directly with the types. I tried something like

Matrix<decltype(remove_cvref_t<T1>::value_type   remove_cvref_t<T2>::value_type) C;

The idea is to strip off any possible references and access the type of the Matrix via ::value_type. I also tried to sprinkle in some typenames but without success.

CodePudding user response:

No, it's not possible to work directly with the types, but you can use std::declval - a function which returns whatever type you want - to "convert" a type to a value:

template <typename T1, typename T2>
auto add(T1&& a, T2&& b) {
    Matrix<decltype(
        std::declval<remove_cvref_t<T1>::value_type>()
          std::declval<remove_cvref_t<T2>::value_type>()
    )> C;
    ...
}

It's still ugly. If all your matrices have the (0,0) operator then you might find that less ugly, and there's nothing wrong with using it; if you absolutely do need value_type as opposed to whatever (0,0) returns, then you can use std::declval.

std::declval can't be called for real - its only purpose is to be used in expressions that don't actually get evaluated, like inside decltype or noexcept.

  • Related