std :: stou가없는 이유는 무엇입니까?


96

C ++ 11은 몇 가지 새로운 문자열 변환 함수를 추가했습니다.

http://en.cppreference.com/w/cpp/string/basic_string/stoul

여기에는 stoi (string to int), stol (string to long), stoll (string to long long), stoul (string to unsigned long), stoull (string to unsigned long long)이 포함됩니다. 그 부재에서 주목할만한 것은 stou (문자열에서 부호없는) 함수입니다. 필요하지 않지만 다른 모든 이유가 있습니까?

관련 : C ++ 11에 "sto {short, unsigned short}"함수가 없습니까?


6
내 질문은 "스톨을 사용하는 것의 명백하지 않은 결점이 있는가"라는 문구를 더 많이 따르도록 의도되었습니다. 분명히 그것은 템플릿 인스턴스화를 망칠 것이지만 내가 고려하지 않는 다른 것이 있습니까? 왜 빠졌는지에 대한 의견은 좋지만 부차적입니다.
David Stone

13
@NicolBolas 왜 이것이 건설적이지 않은지 알 수 없습니다. 이 불일치에 대한 어떤 이유도 볼 수 없으며 답변이 기존의 유효하지만 명백한 이유에 대한 통찰력을 줄 수 있기 때문에 완벽하게 유효한 질문입니다.
Christian Rau

4
때문에 @SethCarnegie 음, 어떤 플랫폼 (그리고 어쩌면 플랫폼의 대부분이)하는 일은, 단지 관련이없는 unsigned long단지가 더있다 unsigned int.
Christian Rau

4
@SethCarnegie : 내 일반적인 컴퓨터에서 unsigned long64 비트와 unsigned int32 비트입니다 . 서로 다른 유형이며 서로 동일하다고 가정 할 수 없습니다.
마이크 시모어

2
@NicolBolas 말했듯이, OP (그리고 나)는 그것이 C ++의 언어 내부에 깊숙이 묻혀있는 완벽한 타당한 이유가있을 수 있기 때문에 그것이 추측 적이라는 것을 모릅니다. 하지만 투기 적이라고 하셨기 때문에 그런 이유는 없다고 생각합니다. 그러나 다시 말하지만 C ++ 11을 담당하는 사람이 여전히 대답 할 수 있습니다. 이것은 "Wah wah, 저 망할 곳이 어디 있습니까? stou"라는 질문이 아니라이 명백한 불일치에 대한 확실한 이유를 묻는 질문입니다. 그런 이유가 없다는 것을 알고 있다면 답변으로 게시하십시오.
Christian Rau

답변:


29

가장 확실한 대답은 C 라이브러리에 해당하는“ strtou” 가없고 C ++ 11 문자열 함수는 모두 C 라이브러리 함수를 둘러싼 얇게 베일 된 래퍼라는 것입니다. std::sto*함수는 미러 strto*이고 함수는를 std::to_string사용 sprintf합니다.


편집 :로 KennyTM는 지적, 모두 stoistol사용 strtol이 존재하는 동안 왜 기본 변환 기능으로,하지만 여전히 신비 stoul그 용도를 strtoul, 해당하는 없습니다 stou.


14
C ++위원회가 왜 그런 C-ish 접근 방식을 선택했는지 아십니까? 뭔가 boost::lexical_cast<>()좀 더 C ++ 방식으로 작업하는 것처럼 보입니다.
Paul Manta 2012 년

2
이러한 구현 세부 사항이 실제로 표준으로 정의되어 있습니까?
궤도

4
@LightnessRacesinOrbit : For sto*, C ++ 11 21.5 / 1 : 효과 : 처음 두 함수는 strtol (str.c_str (), ptr, base)를 호출하고 마지막 세 함수는 strtoul (str.c_str (), ptr, base를 호출합니다. ), strtoll (str.c_str (), ptr, base) 및 strtoull (str.c_str (), ptr, base) 각각.
Mike Seymour 2012 년

12
그것은 C ++ 표준은 중요하지 "... 호출하여 구현해야합니다"라는 않습니다 여부를 C로 인해 ++ 표준 여전히이 세계로-경우 규칙 : 표준이 말한다면 std::sto*, C 라이브러리 함수의 래퍼로 구현되어야하며, 유효한 프로그램은 그들이 비밀리에 다르게 구현되지 않았 음을 알 수 없으며 구현이 유효합니다.

2
완전히 주제에서 벗어난, Boost / lexical_cast와 같은 iostreams를 사용하지 않는 실제적인 이유는 순전히 성능 때문이라고 생각합니다. 나는 iostreams가 strtoul 등에 상당한 차이로 패배한다고 생각합니다.
Kerrek SB

22

나는 왜 stoi존재하지만 그렇지 않은지 모르겠지만와 가설 stou의 유일한 차이점 은 결과가 다음 범위에 있는지 확인하는 것입니다 .stoulstouunsigned

unsigned stou(std::string const & str, size_t * idx = 0, int base = 10) {
    unsigned long result = std::stoul(str, idx, base);
    if (result > std::numeric_limits<unsigned>::max()) {
        throw std::out_of_range("stou");
    }
    return result;
}

(마찬가지로 는 다른 범위 검사 만 있는와 stoi유사 stol하지만 이미 존재하므로 정확히 구현하는 방법에 대해 걱정할 필요가 없습니다.)


stoistol, 또는 stol및 의 차이 stoll는 범위 검사일뿐입니다.
Hossein 2012 년

1
@ 호세인 : 사이 stoistol, 네. 그러나 stolstoll서로 다른 라이브러리 함수를 호출, 범위 체크 만 다르지 않다.
Ben Voigt

0
unsigned long ulval = std::stoul(buf);
unsigned long mask = ~0xffffffffl;
unsigned int uival;
if( (ulval & mask) == 0 )
    uival = (unsigned int)ulval;
else {
    ...range error...
}

마스크를 사용하여 마스크에 표시된 비트 단위의 예상 값 크기로이를 수행하면 64 비트 long과 32 비트 정수뿐만 아니라 32 비트 long과 32 비트 정수에서도이 작업을 수행 할 수 있습니다.

64 비트 long의 경우 ~ 0xffffffffl은 0xffffffff00000000이되어 상위 32 비트가 설정되었는지 확인합니다. 32 비트 long의 경우 ~ 0xffffffffl은 0x00000000이되고 마스크 검사는 항상 0이됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.