Museful
Museful

Reputation: 6959

Templated implicit type conversion operator

I have implemented

template<int M, int N, typename T=double>
class matrix{
    // ...
}

and would like the ability to use matrix<1,1,T> where a T is expected.

How should I accomplish this? Would the following work?

template<typename T>
operator T(matrix<1, 1, T> mat) {
    return mat(0,0);
}

(The reason for even expecting to encounter matrix<1,1,T> is that some matrix expressions have that type. For example, multiplying a matrix<1,3> by a matrix<3,1> evaluates to a matrix<1,1>.)

Upvotes: 1

Views: 57

Answers (2)

Museful
Museful

Reputation: 6959

Put this in the class definition:

template<int Md=M, int Nd=N, typename = std::enable_if_t<Md==1 && Nd==1>>
operator T() const {
    return (*this)(0,0);
}

Upvotes: 0

einpoklum
einpoklum

Reputation: 131515

The code you've listed will not compile, since you're essentially trying to implement a T constructor outside the definition of T; or if it's a fundamental type, or an array, it makes even less sense.

What you can do instead is implement a casting operator within your matrix class - by either adding it to the general template or specializing matrix for M=1 and N=1.

The first option would look like this:

template<int M, int N, typename T=double>
class matrix{
    // ...
    operator T() const {
        static_assert(M == 1 and N==1, 
            "Attempting to treat a matrix with multiple cells as a scalar");
        // code to return the single matrix element
    }
}

and the second:

template<int M, int N, typename T=double>
class matrix{
    // ...
}


template<typename T=double>
class matrix<1, 1, T>{
    // ... some code duplication here with the main template; or maybe
    // actually have different implementation banking on the fact that
    // it's really just a scalar.

    operator T() const {
        // code to return the single matrix element
    }
}

but frankly, I don't think I'd recommend any of these options. I'd probably do one of the following:

  • Alter function which takes a T so that it can "naturally" take 1x1 matrices (e.g. by templating)
  • Alter function which takes a T so that it can "naturally" take any matrix. A lot of scalar work has interesting generalization to matrices.
  • Be explicit about the conversion, perhaps writing a template <typename T> T as_scalar(const matrix<1,1,T> m) function.

Upvotes: 3

Related Questions