vendredi 5 janvier 2018

How to use compile-time ternary operator in C++ to get object member

I have a templated class eglue, which determines its own n_rows and n_cols from one of the parameters passed in, which is guaranteed to have n_rows and n_cols members. The code is as follows:

template<typename> struct isEglueOrMat : std::false_type {};
template<typename T1, operations _op, typename T2> struct isEglueOrMat<eglue<T1, _op, T2>> : std::true_type {};
template<> struct isEglueOrMat<Matrix> : std::true_type {};

template<typename T1, operations _op, typename T2>
class eglue {
public:
    const T1& First;
    const T2& Second;
    const unsigned n_rows;
    const unsigned n_cols;
    eglue(const T1& f, const T2& s) : First(f), Second(s), n_rows(isEglueOrMat<T1>()? f.n_rows:s.n_rows), n_cols(isEglueOrMat<T1>()? f.n_cols:s.n_cols) {}

This doesn't work, failing with the error request for member 'n_rows' in 'f', which is of non-class type 'const float', when I only want to get n_rows from the other item, which will be an eglue or Matrix object.

The other approach I have tried is templated constructors:

template<typename Dummy = void, typename Dummy2 = std::enable_if_t<isEglueOrMat<T1>(), Dummy>> eglue(const T1& f, const T2& s) : First(f), Second(s), n_rows(f.n_rows), n_cols(f.n_cols) {}
template<typename Dummy = void, typename Dummy2 = std::enable_if_t<isEglueOrMat<T2>(), Dummy>> eglue(const T1& f, const T2& s) : First(f), Second(s), n_rows(s.n_rows), n_cols(s.n_cols) {}

This fails with error

type/value mismatch at argument 1 in template parameter list for 'template<bool _Cond, class _Tp> using enable_if_t = typename std::enable_if::type'
     template<typename Dummy = void, typename Dummy2 = std::enable_if_t<isEglueOrMat<T1>(), Dummy>> eglue(const T1& f, const T2& s) : First(f), Second(s), n_rows(f.n_rows), n_cols(f.n_cols) {}
                                                                                            ^
error:   expected a constant of type 'bool', got 'isEglueOrMat<T1>()'

Even though I have successfully used isEglueOrMat<type>() at other points in the code (I will post these if necessary, but I've seen it works in other situations).

I am aware this may be a duplicate or similar to other questions, but I really haven't been able to get this to work... any advice would be much appreciated.

Aucun commentaire:

Enregistrer un commentaire