>

std::string::c_str()  문자열 객체의 현재 값을 나타내는 null로 끝나는 문자 시퀀스 (예 : C- 문자열)를 포함하는 배열에 대한 포인터를 반환합니다.

C ++ 98에서 "프로그램은이 순서에서 어떤 문자도 변경해서는 안된다"는 것이 요구되었다. const char *을 반환하여 권장되었습니다.

C ++ 11에서 "포인터는 문자열 객체가 현재 값을 준수하는 문자를 저장하기 위해 사용하는 내부 배열을 가리키는 포인터를 반환했습니다"라는 내용을 수정하지 않아도됩니다. 이것이 사실입니까?

이 코드는 C ++ 11에서 괜찮습니까?

#include<iostream>
#include<string>
#include<vector>
using namespace std;
std::vector<char> buf;
void some_func(char* s)
{
    s[0] = 'X'; //function modifies s[0]
    cout<<s<<endl;
}
int main()
{
    string myStr = "hello";
    buf.assign(myStr.begin(),myStr.end());
    buf.push_back('\0');
    char* d = buf.data();   //C++11
    //char* d = (&buf[0]);  //Above line for C++98
    some_func(d);   //OK in C++98
    some_func(const_cast<char*>(myStr.c_str())); //OK in C++11 ?
    //some_func(myStr.c_str());  //Does not compile in C++98 or C++11
    cout << myStr << endl;  //myStr has been modified
    return 0;
}

  • 답변 # 1

    와이즈 비즈

    이 요구 사항은 여전히 ​​n3337 초안으로 존재합니다 (게시 된 C ++ 11 표준과 가장 유사한 작업 초안은 N3337입니다).

  • 답변 # 2

    C ++ 11에서 예,

    3 Requires: The program shall not alter any of the values stored in the character array.

    에 대한 제한  여전히 유효합니다. (반품 유형은 c_str() 입니다. 따라서이 기능에는 특별한 제한이 필요하지 않습니다. 와이즈 비즈  프로그램에서 큰 붉은 깃발입니다.)

    그러나 pyzwyz는 , 광고 문안 오류로 인해 효과가있는 것 같습니다. C ++ 14에 대해 구두점이 바뀌면 수정 될 수 있습니다. 따라서 해석은 당신에게 달려 있습니다. 물론이 작업을 수행하는 것이 너무 일반적이므로 라이브러리 구현으로 인해 실패 할 수 없습니다.

    C ++ 11 문구 :

    와이즈 비즈

    C ++ 14 문구 :

    와이즈 비즈

    const 를 통과 할 수 있습니다  서명에서 알 수 있듯이 C 문자열을 기대하는 함수에 대한 읽기 전용 참조로 사용됩니다. 읽기-쓰기 참조를 기대하는 함수는 일반적으로 주어진 버퍼 크기를 예상하고 const_cast 를 작성하여 문자열의 크기를 조정할 수 있습니다.  그 버퍼 내에서, operator[]  구현은 실제로 지원하지 않습니다. 그렇게하려면

    Returns: *(begin() + pos) if pos < size(), otherwise a reference to an object of type T with value charT(); the referenced value shall not be modified.

    가 필요합니다  자신의

    Returns: *(begin() + pos) if pos < size(). Otherwise, returns a reference to an object of type charT with value charT(), where modifying the object leads to undefined behavior.

    를 포함하는 문자열  터미네이터, c_str() 전달  이것은 읽기-쓰기 참조이며 NUL  다시 std::string 를 제거하기 위해  종료하고 라이브러리에 종료 책임을 다시 넘깁니다.

  • 답변 # 3

    c_str ()이 resize 를 반환하면  언어 변호사가 회색 영역이라고 주장 할 수는 있지만 괜찮지 않습니다.

    내가 보는 방식은 간단하다. 메소드의 서명은 그것이 반환하는 포인터가 아무것도 수정하는 데 사용되어서는 안된다고 말합니다.

    또한 다른 의견 제시 자들이 지적했듯이 계약을 위반하지 않는 동일한 일을하는 다른 방법이 있습니다. 따라서 그렇게 할 수는 없습니다.

    그것에 따르면 Borgleader는 여전히 그 언어가 그렇지 않다고 말합니다.

  • 답변 # 4

    NUL

    감사합니다

    와이즈 비즈

    & s[0]
    
    

    포인터 p1과 p2는 정확히 같은 것 같습니다. "프로그램은 문자 배열에 저장된 값을 변경하지 않아야합니다."위의 마지막 두 줄은 모두 불법이며 위험 할 수 있습니다.

    이 시점에서 내 자신의 질문에 대답하는 방법은 원래 std :: string을 벡터에 복사 한 다음 문자를 변경할 수있는 함수에 새 배열에 대한 포인터를 전달하는 것이 가장 안전하다는 것입니다.

    원래 게시물에서 제공 한 이유로 C ++ 11에서이 단계가 더 이상 필요하지 않기를 바랐습니다.

    resize

  • 이전 c++ - 이동 생성자의 초기화 목록에서 std - : move를 사용해야하는 이유는 무엇입니까?
  • 다음 javascript - 새 태그 생성을위한 Select2 이벤트