Просмотр необработанного указателя как диапазона в цикле for на основе диапазона

Как я могу сделать необработанный указатель вести себя как диапазон, для синтаксиса цикла для диапазона.

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

Мотивация:

Теперь это Vox Populi, чтоboost::optional&nbsp;(будущееstd::optional) значение можно рассматривать как диапазон и, следовательно, использовать в цикле для диапазонаhttp://faithandbrave.hateblo.jp/entry/2015/01/29/173613.

Когда я переписал свою собственную упрощенную версию:

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

Используется в качестве

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

Просматривая этот код, я представлял, что он может быть обобщен и на необработанные (обнуляемые) указатели.

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

вместо обычногоif(dptr) std::cout << *dptr << std::endl;, Что хорошо, но я хотел добиться другого синтаксиса выше.

попытки

Сначала я попытался сделать вышеOptional&nbsp;версияbegin&nbsp;а такжеend&nbsp;работать для указателей, но я не мог. Поэтому я решил быть явным в типах и удалить все шаблоны:

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

Почти там, это работает для

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

Но это не работает дляпредположительно эквивалентный&nbsp;петля для диапазона:

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

Два компилятора говорят мне:error: invalid range expression of type 'double *'; no viable 'begin' function available

Что здесь происходит? Есть ли магия компилятора, которая запрещает дальний цикл работать для указателей. Я делаю неправильное предположение о синтаксисе дальнего цикла?

Как ни странно, в стандарте есть перегрузка дляstd::begin(T(&arr)[N])&nbsp;и это очень близко к этому.

Обратите внимание и секунду, хотя

Да, идея глупа, потому что, даже если это возможно, это очень сбивает с толку:

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

будет перебирать только первый элемент. Более понятный и реалистичный способ - сделать что-то вроде обходного пути, предложенного @Yakk:

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

Таким образом, ясно, что мы выполняем итерации только по одному элементу и этот элемент является необязательным.

Хорошо, хорошо, я вернусь кif(ptr) ... use *ptr.