2012-02-13 19 views
7

Bây giờ, chúng ta sớm có các chữ cái do người dùng định nghĩa (UDL), ví dụ như GCC 4.7, tôi đang háo hức đợi thư viện đơn vị (chẳng hạn như Boost.Units) để giảm bớt các biểu thức của các chữ như 1+3i, 3m, 3meter hoặc 13_meter. Có ai đã viết phần mở rộng cho Boost.Units bằng cách sử dụng UDL hỗ trợ hành vi này không?Physical Boost.Units Literals do người dùng định nghĩa

+1

Xét rằng trình biên dịch duy nhất có hỗ trợ UDL là GCC, và thậm chí sau đó chỉ trong bản phát hành không ổn định, tôi đoán là không. Ngoài ra, UDL không bắt đầu bằng '_' được dành riêng cho các tiêu chuẩn tương lai; bạn không thể tự viết chúng. –

+0

Điều đó là tốt để biết! Tôi chỉ tự hỏi làm thế nào UDL có thể xung đột với hậu tố chữ số hiện tại 'l',' f' và 'd'. Yêu cầu '_' trả lời câu hỏi đó. –

Trả lời

5

Không có ai đi ra với phần mở rộng như vậy. Chỉ có gcc (và có thể là IBM?) Có UDL vì vậy nó có thể là một lúc. Tôi hy vọng một số loại đơn vị làm cho nó thành tr2 đang bắt đầu từ bây giờ. Nếu điều đó xảy ra, tôi chắc rằng UDL cho các đơn vị sẽ xuất hiện.

này hoạt động:

// ./bin/bin/g++ -std=c++0x -o units4 units4.cpp 

#include <boost/units/unit.hpp> 
#include <boost/units/quantity.hpp> 
#include <boost/units/systems/si.hpp> 

using namespace boost::units; 
using namespace boost::units::si; 

quantity<length, long double> 
operator"" _m(long double x) 
{ return x * meters; } 

quantity<si::time, long double> 
operator"" _s(long double x) 
{ return x * seconds; } 

int 
main() 
{ 
    auto l = 66.6_m; 
    auto v = 2.5_m/6.6_s; 
    std::cout << "l = " << l << std::endl; 
    std::cout << "v = " << v << std::endl; 
} 

Tôi nghĩ rằng nó sẽ không quá khó để đi qua bạn đơn vị yêu thích và thực hiện điều này.

Liên quan đến việc đưa chúng vào thư viện: Toán tử theo nghĩa đen là các hàm phạm vi không gian tên. Sự cạnh tranh cho hậu tố sẽ trở nên xấu xí. Tôi sẽ (nếu tôi là tăng) có

namespace literals 
{ 
... 
} 

Sau đó, người dùng có thể tăng cường làm

using boost::units::literals; 

cùng với tất cả các decls sử dụng khác mà bạn thường sử dụng. Sau đó, bạn sẽ không bị clobbered bởi std::tr2::units ví dụ. Tương tự như vậy nếu bạn cuộn của riêng bạn.

+1

Thất vọng # 1: Nhà điều hành văn chương chỉ có thể lấy một vài loại đối số. Nó sẽ là tốt đẹp để có các phiên bản mà trở lại nổi và đôi cũng như dài gấp đôi để tính toán không được thúc đẩy lên đến dài gấp đôi tất cả các thời gian? ADL sẽ không chọn theo kiểu trả về - các không gian tên chính xác cụ thể và sử dụng? Ugh. – emsr

+1

Nỗi lo # 2: ngoài tất cả các đơn vị, nó sẽ là tốt đẹp để có ít nhất phổ biến bội số. ví dụ. không chỉ "m" nhưng "km", "cm", "mm" cho độ dài, "Hz", "kHz", "MHz", "GHz" cho tần suất. Nó có thể tẻ nhạt - hoặc liên quan đến một số macro. – emsr

+0

Tôi tự hỏi tại sao quảng bá cho một độ chính xác cao hơn _ là một vấn đề cho bạn ... – celticminstrel

3

Theo tôi, không có nhiều lợi ích khi sử dụng chữ cho Boost.Units, bởi vì cú pháp mạnh hơn vẫn có thể đạt được với các khả năng hiện có.

Trong trường hợp đơn giản, có vẻ như chữ là cách để đi, nhưng chẳng bao lâu bạn thấy rằng nó không phải là rất mạnh mẽ. Ví dụ: Ví dụ, bạn vẫn phải xác định các chữ cho các đơn vị kết hợp, làm thế nào để bạn thể hiện 1 m/s (một mét mỗi giây)?

Hiện tại:

auto v = 1*si::meter/si::second; // yes, it is long 

nhưng với literals?

// fake code 
using namespace boost::units::literals; 
auto v = 1._m_over_s; // or 1._m/si::second; or 1._m/1_s // even worst 

Một giải pháp tốt hơn có thể đạt được với các tính năng hiện có. Và đây là những gì tôi làm:

namespace boost{namespace units{namespace si{ //excuse me! 
namespace abbreviations{ 
    static const length    m = si::meter; 
    static const time    s = si::second; 

    // ... 
} 
}}} // thank you! 

using namespace si::abbreviations; 
auto v = 1.*m/s; 

Trong cùng một cách bạn có thể làm: auto a = 1.*m/pow<2>(s); hoặc mở rộng các chữ viết tắt hơn nếu bạn muốn (ví dụ static const area m2 = pow<2>(si::meter);)

gì khác ngoài này nào bạn muốn?

Có lẽ một giải pháp kết hợp có thể là cách

auto v = 1._m/s; // _m is literal, /s is from si::abbreviation combined with operator/ 

nhưng sẽ có mã để nhiều dư thừa và đạt được là tối thiểu (thay thế * bởi _ sau số.)

Một nhược điểm của giải pháp của tôi là nó polutes không gian tên với một tên thư chung. Nhưng tôi không thấy cách nào khác ngoài việc thêm dấu gạch dưới (vào đầu hoặc cuối của chữ viết tắt), như trong 1.*m_/s_ nhưng ít nhất tôi có thể xây dựng các biểu thức đơn vị thực.