2014-12-18 18 views
21

Để sử dụng operator""s cho std::string bạn phải làm using namespace std::string_literals. Nhưng các chữ cái do người dùng xác định không bắt đầu bằng _ được đặt trước, vì vậy xung đột có thể không thể là một cái cớ. Các khác operator""s là từ std::chrono nhưng đó là cho int literals, do đó, không có xung đột ở đó.Tại sao toán tử được ẩn trong một không gian tên?

Lý do cho việc này là gì?

+0

Oh người đàn ông ... Tôi nhớ đã nhìn thấy một cuộc nói chuyện về điều này, hoặc là CppCon hoặc Boostcon, nhưng tôi không thể nhớ tại sao điều này. – Borgleader

+0

Trong khi tôi không biết lý do chính xác, có vẻ hợp lý để tránh gây ô nhiễm không gian tên chung mà hậu tố ngắn như vậy. – Aleph

+1

@Borgleader https://www.youtube.com/watch?v=dTeKf5Oek2c Đó là phần đầu video. –

Trả lời

19

Thực tế, có hai lý do tại sao literals được đưa vào không gian tên:

  1. Nó được coi là không mong muốn mà người dùng sẽ sử dụng using namespace std; chỉ để có được giữ của literals tương ứng. Có các chữ được khai báo trong các không gian tên cụ thể cho các chữ cái này không gây ra vấn đề.
  2. Tùy thuộc vào miền có thể mong muốn sử dụng s làm hậu tố cho một mục khác. Đã có một hậu tố khác s có nghĩa là giây nhưng chúng không thực sự xung đột.

Trong video of STL's CppCon 2014 talk (được đăng bởi remyable trong một chú thích) Stephan T. Lavavej giải thích thiết kế tổng thể của chữ trong C++ 14 và nó khá rõ ràng rằng họ là không nghĩa vụ phải được trong không gian tên toàn cầu ! Thay vào đó, hậu tố chữ trong thư viện chuẩn sống trong một hệ thống phân cấp của inline không gian tên cho phép người dùng kiểm soát chi tiết hơn các chữ được tạo sẵn. Ví dụ, các hậu tố đen cho các chuỗi được khai báo như thế này (21,3 [string.classes] đoạn 1):

namespace std { 
    inline namespace literals { 
     inline namespace string_literals { 
      string operator"" s(char const* str, size_t len); 
     } 
    } 
} 

hệ thống cấp bậc này của inline không gian tên làm cho nó có thể cho người sử dụng để có được những lựa chọn thích hợp của hậu tố đen:

  • using namespace std; - bạn nhận được mọi thứ trong thư viện chuẩn C++, bao gồm hậu tố chữ, không có bất kỳ bằng cấp nào.
  • using namespace std::literals; - bạn sẽ nhận được tất cả hậu tố được xác định trong thư viện chuẩn C++.
  • using namespace std::string_literals; - bạn nhận được tất cả các hậu tố chữ áp dụng cho chuỗi.
  • using namespace std::literals::string_literals; - có, bạn có thể làm điều đó nhưng bạn thực sự không nên: tương đương với using namespace std::string_literals;.

Rõ ràng, ủy ban sẽ không cố gắng nhiều nếu nó đã xem xét ý tưởng có khả năng gây ô nhiễm không gian tên chung với hậu tố chữ, mặc dù chúng thậm chí không xung đột với bất kỳ hậu tố chữ nào của người dùng.

+0

Tôi không bị thuyết phục. Mã thư viện không chuẩn của người dùng không thể khai báo 'toán tử' 's', hoặc có thể không? – milleniumbug

+1

@milleniumbug: đúng: các chữ cái do người dùng xác định cần phải bắt đầu bằng '_'.Xung đột được giải quyết không phải với mã người dùng mà là với các lớp thư viện chuẩn khác. Off-hand Tôi không thể nghĩ ra một ví dụ thuyết phục nhưng một khi chúng ta có một thư viện mạng thì có thể sẽ rất tuyệt khi tạo một socket bằng cách sử dụng '" 127.0.0.1:80 "s'. ... và đối số khác, không muốn ủy thác mã gây ô nhiễm với 'sử dụng không gian tên std;' vẫn giữ nguyên: theo tôi biết bạn không thể khai báo 'using'-chọn lọc chỉ cho một toán tử. –

+1

@milleniumbug Đề xuất 'string_view' là một ứng cử viên tiềm năng khác cho chữ' '" s', mặc dù nó cũng đã sử dụng '" "sv' trong quá khứ để tránh xung đột. (Không có toán tử theo nghĩa đen nào trong bản nháp hiện tại.) Không có giải pháp nào nếu có, sẽ được giữ lại (ví dụ: các chữ '' 's' đồng thời trong các không gian tên khác nhau hoặc cách khác). –

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