Ver un puntero sin formato como un rango en un bucle for basado en rango

¿Cómo puedo hacer que un puntero sin formato se comporte como un rango, para una sintaxis de bucle de rango?

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

Motivación:

Ahora es vox populi que unboost::optional (futurostd::optional) el valor se puede ver como un rango y, por lo tanto, se puede usar en un bucle for rangehttp://faithandbrave.hateblo.jp/entry/2015/01/29/173613.

Cuando reescribí mi propia versión simplificada:

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;
    }
}

Usado como

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

Mientras miraba ese código, imaginé que también podría generalizarse a punteros sin procesar (anulables).

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

en lugar de lo habitualif(dptr) std::cout << *dptr << std::endl;. Lo cual está bien, pero quería lograr la otra sintaxis anterior.

Intentos

Primero intenté hacer lo anteriorOptional versión debegin yend trabajo para punteros pero no pude. Así que decidí ser explícito en los tipos y eliminar todas las plantillas:

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;
    }
}

Casi allí, funciona para

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

Pero no funciona para elsupuestamente equivalente bucle de rango:

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

Dos compiladores me dicen:error: invalid range expression of type 'double *'; no viable 'begin' function available

Que esta pasando? ¿Existe una magia de compilación que prohíba que el bucle a distancia funcione para los punteros? ¿Estoy haciendo una suposición errónea sobre la sintaxis de bucle a distancia?

Irónicamente, en el estándar hay una sobrecarga parastd::begin(T(&arr)[N]) y esto está muy cerca de eso.

Nota y un segundo aunque

Sí, la idea es tonta porque, incluso si es posible, esto sería muy confuso:

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

iteraría solo sobre el primer elemento. Una solución más clara y realista sería hacer algo como la solución propuesta por @Yakk:

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

De esta manera, está claro que estamos iterando sobre un solo elemento y que ese elemento es opcional.

Ok, ok, volveré aif(ptr) ... use *ptr.

Respuestas a la pregunta(2)

Su respuesta a la pregunta