lundi 3 juillet 2017

Result of decltype in const methods

The C++11 decltype returns the type of the expression given to it as that type was declared. But this can differ from the type of the expression as it is actually accessible:

template<typename T>
struct Ref {
    Ref(T&) { }
};

#define GENREF(r, v) Ref<decltype(v)> r{v}
//#define GENREF(r, v) Ref<typeof(v)> r{v}

struct Problem {
    void doit_c() const { GENREF(rn, n); }
    void doit_nc()      { GENREF(rn, n); }
    int n;
};

int main() {
    int i;
    const int ci = 0;
    Problem pr;

    // decltype == typeof == int
    GENREF(ri, i);
    pr.doit_nc();

    // decltype == typeof == const int
    GENREF(rci, ci);
    GENREF(rcci, static_cast<const int&>(i));

    // typeof == const int, decltype == int (!)
    pr.doit_c();

    return 0;
}

In the example the Ref struct is just used to cause a compile error if T does not match the actual constructor argument. The Problem::doit_c() method is where decltype(n) returns a non-const result, even though n is const in this context.

If one switches from the standard decltype to the GNU extension typeof, this seems to take the const-ness of the method into account.

Now my question: Is there a C++11 / C++14 / C++17 complient alternative to decltype() / typeof() that behaves "correctly" (as in: no compile error above) for expressions like the declaration in the const-method above?

Aucun commentaire:

Enregistrer un commentaire