samedi 1 juillet 2017

How to template a function with const/nonconst pointer/reference arguments

Let say I have following set of functions:

typedef uint8_t byte;

inline byte *as_bytes(char *data) {
    return reinterpret_cast<byte*>(data);
}

inline byte *as_bytes(std::vector<byte> &v) {
    return &v[0];
}

inline byte *as_bytes(QByteArray &a) {
    return as_bytes(a.data());
}

inline const byte *as_cbytes(const char *data) {
    return reinterpret_cast<const byte*>(data);
}

inline const byte *as_cbytes(const std::vector<byte> &v) {
    return &v[0];
}

inline const byte *as_cbytes(const QByteArray &a) {
    return as_cbytes(a.data());
}

Question: can I template these functions so that constness and pointer/reference type deduction will work properly? Result that I want to see might look like:

template<typename T>
inline byte *as_bytes(T data) {
    return reinterpret_cast<byte*>(data);
}

template<>
inline byte *as_bytes(std::vector<byte> &v) {
    return &v[0];
}

template<>
inline byte *as_bytes(QByteArray &a) {
    return as_bytes(a.data());
}

But of course this code won't work for me for 2 reasons:

  • I want constness of argument to be deduced and forwarded it to a return type;
  • Since we're talking about functions, specialization for std::vector and QByteArray won't work as expected since always template<typename T> inline byte *as_bytes(T data) will be chosen because of function overload.

Maybe there are some C++11/14/17 mechanisms to solve these problems and end up with 3 pretty functions?

Aucun commentaire:

Enregistrer un commentaire