linearly interpolate NA values in Rcpp::NumericVector
As you suggest, the code does look very "pointery".  I think it might be made clearer with use of some standard algorithms:


std::adjacent_find() (with suitable predicate functions) to find a number followed by NA, or a NA followed by a number.
std::generate() (with suitable generator function) to populate a series of values from one iterator to another.


With those, you won't need any arithmetic on iterators other than a subtraction to find the number of elements you're interpreting.



The form of such a solution is something like this (untested):

#include &lt;Rcpp.h&gt;
#include &lt;algorithm&gt;

constexpr auto is_na = Rcpp::NumericVector::is_na;

//[[Rcpp::export]]
Rcpp::NumericVector naLinInt(Rcpp::NumericVector x) {
    // This function linearly interpolates to fill sequences of NA
    // values surrounded by valid numbers.
    static auto const detect_start_na = [](auto a, auto b){
        return !is_na(a) &amp;&amp; is_na(b);
    };
    static auto const detect_end_na = [](auto a, auto b){
        return is_na(a) &amp;&amp; !is_na(b);
    };

    auto start = x.begin();

    while (true) {
        // Find transitions to and from NA values.  If we hit end of
        // vector whilst looking, our work is done.
        auto num_to_na = std::adjacent_find(start, x.end(), detect_start_na);
        auto na_to_num = std::adjacent_find(start, x.end(), detect_end_na);
        if (na_to_num == x.end()) {
            break;
        }

        // At this point, num_to_na points to the last number before
        // an interpolation block, and na_to_num points to the last NA
        // of that block.

        ++na_to_num;            // Now, both iterators point to numbers.
        auto const base = *num_to_na;
        auto const target = *na_to_num;

        // To count rails rather than posts, measure difference before
        // incrementing the start position.
        auto const gaps = std::distance(na_to_num, num_to_na);

        ++num_to_na;
        // Now both iterators point immediately *after* transition.

        auto const make_value = [base, target, gaps, i = std::size_t{0}]()
            mutable { return base + (++i * (target - base) / gaps); };
        std::generate(na_to_num, num_to_na, make_value);

        // Advance onwards
        start = na_to_num;
    }

    return x;
}


There are a couple of iterator increments there (because std::adjacent_find returns an iterator to the first of the matching pair), but there's quite a lot less arithmetic than the original.    

Although this is longer than the original, much of the difference is the comments that help the reader understand how the state changes through the loop.  That's something that I think is an improvement (though perhaps the terms "rails" and "posts" require a link to a definition of fencepost error for the uninitiated).