Caracteres extraídos por istream >> double

Código de amostrana Coliru:

#include <iostream>
#include <sstream>
#include <string>

int main()
{
    double d; std::string s;

    std::istringstream iss("234cdefipxngh");
    iss >> d;
    iss.clear();
    iss >> s;
    std::cout << d << ", '" << s << "'\n";
}

Estou lendo o N3337 aqui (presumivelmente é o mesmo que o C ++ 11). Em [istream.formatted.arithmetic], temos (parafraseado):

operator>>(double& val);

Como no caso dos insersores, esses extratores dependem do objeto num_get <> (22.4.2.1) da localidade para realizar a análise dos dados do fluxo de entrada. Esses extratores se comportam como funções de entrada formatadas (conforme descrito em 27.7.2.2.1). Após a construção de um objeto de sentinela, a conversão ocorre como se fosse realizada pelo seguinte fragmento de código:

typedef num_get< charT,istreambuf_iterator<charT,traits> > numget;
iostate err = iostate::goodbit;
use_facet< numget >(loc).get(*this, 0, *this, err, val);
setstate(err);



Olhando para 22.4.2.1:

Os detalhes desta operação ocorrem em três etapas
- Etapa 1: determinar um especificador de conversão
- Estágio 2: extraia os caracteres de in e determine um valor de char correspondente para o formato esperado pela especificação de conversão determinada no estágio 1.
- Etapa 3: armazenar resultados



Na descrição do Estágio 2, é muito longo para eu colar a coisa toda aqui. No entanto, diz claramente que todos os caracteres devem ser extraídos antes da tentativa de conversão; e ainda que exatamente os seguintes caracteres devem ser extraídos:

qualquer um0123456789abcdefxABCDEFX+-O localdecimal_point()O localthousands_sep()

Por fim, as regras para o Estágio 3 incluem:

- Para um valor de ponto flutuante, a funçãostrtold.

O valor numérico a ser armazenado pode ser um dos seguintes:

- zero, se a função de conversão falhar ao converter o campo inteiro.

Tudo isso parece especificar claramente que a saída do meu código deve ser0, 'ipxngh'. No entanto, ele realmente gera outra coisa.

Isso é um bug do compilador / biblioteca? Existe alguma disposição que estou ignorando para uma localidade para alterar o comportamento do Estágio 2? (Nooutra pergunta&nbsp;alguém postou um exemplo de sistema que realmente extrai os caracteres, mas também extraiipxn&nbsp;que não estão na lista especificada em N3337).

Atualizar

Como apontado por perreal, este texto do estágio 2 é relevante:

Se o descarte for verdadeiro, se '' ainda não tiver sido acumulado, a posição do personagem será lembrada, mas o personagem será ignorado. Caso contrário, se '' já tiver sido acumulado, o personagem será descartado e o estágio 2 será encerrado. Se não for descartado, é feita uma verificação para determinar sec&nbsp;é permitido como o próximo caractere de um campo de entrada do especificador de conversão retornado pelo Estágio 1. Nesse caso, ele é acumulado.

Se o caractere for descartado ou acumulado, o in será avançado por ++ in e o processamento retornará ao início do estágio 2.

Portanto, o estágio 2 pode terminar se o personagem estiver na lista de caracteres permitidos, mas não for um caractere válido para%g. Não diz exatamente, mas presumivelmente isso se refere à definição defscanf&nbsp;do C99, que permite:

uma sequência não vazia de dígitos decimais opcionalmente contendo um caractere de ponto decimal e, em seguida, uma parte opcional do expoente, conforme definido em 6.4.4.2;um 0x ou 0X, então uma sequência não vazia de dígitos hexadecimais opcionalmente contendo um caractere de ponto decimal e, em seguida, uma parte opcional do expoente binário, conforme definido em 6.4.4.2;INF ou INFINITY, ignorando maiúsculas e minúsculasNAN ou NAN (opção n-char-sequence), ignorando o caso na parte NAN, em que:

e também

Em outro local que não o "C", podem ser aceitas formas adicionais de sequência de assunto específicas do local.

Então, na verdade, a saída do Coliru está correta; e de fato o processamentodevo&nbsp;tentativa de validar a sequência de caracteres extraídos até uma entrada válida para%g, ao extrair cada caractere.

Próxima pergunta: é permitido, como no tópico ao qual vinculei anteriormente, aceitari , n, p&nbsp;etc no estágio 2?

Esses são caracteres válidos para%g&nbsp;, no entanto, eles não estão na lista de átomos que a Etapa 2 pode ler (ou seja,c == 0&nbsp;para minha última citação, para que o personagem não seja descartado nem acumulado).