Speeding up string splitting in Rcpp/Cpp
Remove unnecessary steps

for (int i = 0; i &lt; field_number - 1; ++i) 
{ /*read discard*/ }
double value;
// read the needed value now


This will make sure that it will not do unnecessary steps if the value needed is the very first one.

Do not copy around

I believe Rcpp would provide some way to access underlying char*. That can be used to construct std::string_view, or use the char* directly.

Use better standard library functions

My first candidate is famous (infamous) function called std::from_chars. It was accepted in C++17, but the support for that is only available with VC++'s standard library (I'm as surprised as you are, the reader, though getting FP parsing right is very hard). Basically it ignores all of the limitations of standard streams, from buffer structures to locales.

The second candidate would be std::strtod, or some such. Notice that std::stod is not a good alternative, because it requires copying parts of the string.

Going beyond standard

One of the good options is fmtlib. It has convenient interface, and is actively developed. Part of it is event coming to standard library, but unfortunately not the one we are interested in.

I'm not sure how faster it will get, but perhaps Boost.Spirit may be a good candidate. It will certainly be strong spirits to your compiler.

Facts

Of course, the benchmarks will tell which way is better. May be everything I've told is heresy. 

Alternative implementation

#include &lt;charconv&gt;
#include &lt;string_view&gt;
#include &lt;cmath&gt;

double strparse(std::string_view s, int field, int a, int b) {
    double candidates[3];
    auto format = std::chars_format::fixed;
    auto start_point = s.data();
    auto end_point = s.data() + s.size();
    switch (field) {
    case 0:
        start_point = std::from_chars(start_point, end_point, candidates[0], format);
    case 1:
        start_point = std::from_chars(start_point, end_point, candidates[1], format);
    case 2:
        start_point = std::from_chars(start_point, end_point, candidates[2], format);
    }

    double ad = a;
    double bd = b;
    return std::abs(ad + bd - candidates[field]);
}


Well, here you have it. No copying around, manual loop unroll to prevent unnecessary steps, exact flags to maximize performance in standard library calls.

Godbolt link.

Unfortunately I do not have convenient access to a windows machine to test the implementation.