UPDATE: There is a proposal to change the meaning of auto
in certain situations.
Implicit Evaluation of “auto” Variables and Arguments by Joel Falcou and others.
The implicit evaluation shall:
- Enable class implementers to indicate that objects of this class are evaluated in an auto statement;
- Enable them to determine the type of the evaluated object;
...
C++11's auto
keyword is great.
However in my opinion if a type is Not Regular (see for example, What is a "Regular Type" in the context of move semantics?) the usage of auto
becomes tricky.
Is there a way to disable the auto
declaration for such type?
Suppose one has a ref
class that emulates a reference
double 5.;
ref<double> rd = d; // `ref` behaves like a reference, so it is not a regular type
ref<double> rd2 = rd; // `ref` can be (syntactically) copy constructible, (it is not regular for other reason)
auto r = rd; // now r is not `double`, but EVEN WORST it is `ref<double>`.
(in real life it would be a more complicated class, the important point is that the class at hand it is not regular.)
The only way I found auto r = rd
not to work (give a compile error) is to make the class non copyable, however I need the class to have copy constructor (with a special semantics, but a copy constructor still).
Is there a way to disable a syntax auto r = rd
somehow? when decltype(rd)
is not regular.
(Even better could be to be able somehow to tell the compiler what auto
should do precisely).
Note: This is not a very artificial problem, one could see that this type of problem is at the core of std::vector<bool>::reference
(which is also a reference wrapper). Disabling (somehow) the syntax auto b = v[10]
wouldn't solve the problem of std::vector<bool>
but it will make bad usage harder.
Am I missing something? Should I change some other part of the design? Should the non-regular classes have a type trait that would help the compiler determine a more general auto (for example deduce bool
for auto b = v[10]
where std::vector<bool> v
.)
static_assert
where you assign a possibility? – Imbibeoperator=
, or even delete it. The problem is allowing thisauto r = rd
syntax, and allowing it with the wrong meaning (that it seems impossible to change in C++). The lineauto r = rd
is not an assignment, but a construction with (the wrong) type deduction. (to be more specific, for a "reference-like type" it is (or should be) the binding operation). – Stairheadref.get()
. Constructing from that should be unambiguous. – Janinareference_wrapper
necessarely (in factreference_wrapper
is not what it seem, see #34236318).ref
in my example is a type that has the semantics of a reference. In fact I could make the class such thatauto r=static_cast<double>(rd)
or as you sayauto r=rd.get()
, but the problem is thatauto r = rd
still conceptually does the wrong things and it is too easy to be misused. (BTW,auto b = (bool)v[10]
works, but it not better thanbool b = v[10]
). – Stairheadauto
is defined to do a very specific thing, and this thing is exactly the same as what happens in template argument deduction. If you propose to disableauto
in some cases, you probably should also disable template argument deduction in those same cases, for consistency's sake. – Statisticianauto&&
will still be possible. – Printerref<double> rd2 = rd1.pseudo_copy();
, wherepsuedo_copy
returns a type that is also not copyable, but can be used to construct aref<double>
. – Yawn