2014-11-17 14 views
8

Tôi chỉ cần chạy vào một số hiểu lầm: ít nhất là trong libC++ thực hiện std :: nghiệm :: string_view có việc thực hiện ngắn gọn như sau:string_view hành vi khi đi qua std :: string tạm

template <class _CharT, class _Traits....> 
class basic_string_view { 
public: 
    typedef _CharT value_type; 
    ... 
    template <class _Allocator> 
    basic_string_view(const basic_string<_CharT, _Traits, _Allocator>& str): 
     __data(str.data()), __size(str.size()) 
    { 
    } 

private: 
    const value_type* __data; 
    size_type __size; 
}; 

Liệu thực hiện này ngụ ý rằng nếu chúng ta chuyển biểu thức rvalue cho hàm tạo này, chúng ta sẽ nhận được hành vi không xác định khi sử dụng __data sau khi xây dựng?

+1

Yeah. 'String_view' chỉ là tham chiếu được tôn vinh. – Rapptz

+1

[Xem thêm] (http://stackoverflow.com/q/20803826/596781). –

Trả lời

13

Đúng vậy. A string_view là một trình bao bọc không có chủ sở hữu với các ngữ nghĩa tham chiếu chỉ được sử dụng khi chuỗi được giới thiệu không cho phép sử dụng chế độ xem.

Các trường hợp sử dụng điển hình là trong các thông số chức năng mà chuỗi thực tế cuộc sống trong suốt thời gian của cuộc gọi chức năng và các cơ quan chức năng không bao giờ lưu quan điểm, nhưng chỉ đọc nó:

void foo(std::experimental::string_view message) // pass by value 
{ 
    std::cout << "You said, '" << message << "'.\n"; 
} 

Cách sử dụng:

foo("Hello");  // OK, string literal has static storage 
foo(s);    // OK, s is alive 
foo(s.substr(1)); // OK, temporary lives until end of full-expression 

các đạo đức là: Nếu bạn chỉ cần chuỗi trong suốt thời gian của cơ quan chức năng, cung cấp cho các chức năng một tham số string_view, và nó đều có thể liên kết với bất kỳ loại argume stringoid nt. Bạn không cần mẫu chức năng, sao chép string_view s là giá rẻ và bạn sẽ nhận được một số thao tác cơ bản gọn gàng miễn phí. Ngược lại, bao giờ lưu trữ một string_view, nhưng luôn luôn lưu trữ một string:

struct X 
{ 
    X(std::experimental::string_view s) : s_(s) {} 

    std::string s_;  // NEVER have a string_view class member! 
}; 
+1

"Không bao giờ" là một chút khắc nghiệt nhưng nếu bạn lưu trữ nó thì bạn cần phải chăm sóc giống như bạn sẽ có nếu lưu trữ một "char *" – plugwash

+1

@plugwash: Có thể. Nhưng tôi muốn nói rằng bạn chắc chắn sẽ tắt tin nhắn nếu bạn đã lưu trữ chế độ xem. Có, trong một lớp học tạm thời chỉ được sử dụng như một giá trị bạn * có thể * có thể sử dụng điều này, nhưng mã như vậy có lẽ tốt hơn bằng văn bản với lambdas làm cho nó rõ ràng rằng chuỗi xem outlives có thể gọi. –

Các vấn đề liên quan