vendredi 23 décembre 2016

Why const lvalue reference has priority over const rvalue reference

Why there is no ambiguity?

struct B {};
struct C {};

struct A
{
    A(B const &, C const &) {}
    A(B const &&, C const &&) = delete;
#if 0
    A(B const &, C const &&) = delete;
    A(B const &&, C const &) = delete;
#endif
};

B const b() { return {}; } // const result type may make
C const c() { return {}; } // for some user-defined types

int main()
{
    A a0{B{}, C{}}; // I want to prohibit this
    A a1{b(), c()}; // and this cases
    B const bb{};
    C const cc{};
    A a2{b(), cc}; // But surely I also want to prohibit this
    A a3{bb, c()}; // and this cases to compile
}

Here I want to store lvalue const references to B and C instances into the instance of A. Of course I want to ensure, that lifetime of referenced objects overcomes the lifetime of A's instance.

To achieve this I just = delete; overloadings for B &&, B const &&, C && and C const &&.

Above approach works perfectly for conversion-constructors (i.e. unary ones). But it turns out, that for higher arities I have to explicitly = delete; all the combinatorically possible combinations, which encloses const rvalue reference versions of parameters of interest.

Then I think: "Why there is no an ambiguity?", — because the ambiguity should also prevent compilation of wrong code in the above case.

So question is: "Why?".

Aucun commentaire:

Enregistrer un commentaire