Anzeigen eines rohen Zeigers als Bereich in einer bereichsbasierten for-Schleife

Wie kann ich einen rohen Zeiger für eine for-range-Schleifensyntax wie einen Bereich verhalten lassen?

double five = 5;
double* dptr = &five;
for(int& d : dptr) std::cout << d << std::endl;// will not execute if the pointer is null

Motivation

s ist jetzt vox populi, dass einboost::optional (Zukunftstd::optional) Wert kann als Bereich angesehen und daher in einer for range-Schleife verwendet werdenhttp: //faithandbrave.hateblo.jp/entry/2015/01/29/17361.

Wenn ich meine eigene vereinfachte Version neu geschrieben habe:

namespace boost {
    template <class Optional>
    decltype(auto) begin(Optional& opt) noexcept{
        return opt?&*opt:nullptr;
    }

    template <class Optional>
    decltype(auto) end(Optional& opt) noexcept{
        return opt?std::next(&*opt):nullptr;
    }
}

Benutzt al

boost::optional<int> opt = 3;
for (int& x : opt) std::cout << x << std::endl;

Während ich diesen Code betrachtete, stellte ich mir vor, dass er auch auf unformatierte (nullfähige) Zeiger verallgemeinert werden könnte.

double five = 5;
double* dptr = &five;
for(int& d : dptr) std::cout << d << std::endl;

anstelle des üblichenif(dptr) std::cout << *dptr << std::endl;. Welches ist in Ordnung, aber ich wollte die andere Syntax oben erreichen.

Versuch

Zunächst habe ich versucht, das oben genannte zu machenOptional Version vonbegin undend Arbeit für Zeiger, aber ich konnte nicht. Also habe ich mich entschlossen, in den Typen explizit zu sein und alle Templates zu entfernen:

namespace std{ // excuse me, this for experimenting only, the namespace can be removed but the effect is the same.
    double* begin(double* opt){
        return opt?&*opt:nullptr;
    }
    double* end(double* opt){
        return opt?std::next(&*opt):nullptr;
    }
}

Fast da, es funktioniert für

for(double* ptr = std::begin(dptr); ptr != std::end(dptr); ++ptr) 
    std::cout << *ptr << std::endl;

Aber es funktioniert nicht für die angeblich gleichwertig for-range-Schleife:

for(double& d : dptr) std::cout << d << std::endl;

Zwei Compiler sagen mir:error: invalid range expression of type 'double *'; no viable 'begin' function available

Was ist los? Gibt es eine Compiler-Magie, die es der Ranging-Schleife verbietet, für Zeiger zu arbeiten? Mache ich eine falsche Annahme über die Ranging-Loop-Syntax?

Ironischerweise gibt es im Standard eine Überlastung fürstd::begin(T(&arr)[N]) und das ist sehr nah dran.

Note und eine Sekunde obwohl

Ja, die Idee ist albern, denn selbst wenn das möglich ist, wäre das sehr verwirrend:

double* ptr = new double[10];
for(double& d : ptr){...}

würde nur das erste Element durchlaufen. Eine klarere und auch realistischere Problemumgehung wäre die von @Yakk vorgeschlagene Problemumgehung:

for(double& d : boost::make_optional_ref(ptr)){...}

Auf diese Weise wird deutlich, dass nur ein Element durchlaufen wird und dieses Element optional ist.

Ok, ok, ich gehe zurück zuif(ptr) ... use *ptr.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage