2012-02-13 29 views
7

現在我們很快就擁有了用戶定義的文字(UDL),例如在GCC 4.7中,我急切地等待使用它們的(物理)單元庫(例如Boost.Units)以簡化文字的表達,如1+3i,3m,3meter13_meter。有誰寫過擴展名爲的Boost.Units使用UDL支持這種行爲?物理Boost.Units用戶定義的文字

+1

考慮到唯一支持UDL的編譯器是GCC,即使只在不穩定版本中,我也猜不到。另外,不以'_'開始的UDL被保留用於未來的標準;你不能自己寫。 – 2012-02-14 01:56:28

+0

很高興知道!我只是想知道UDL如何與當前的數字文字後綴'l','f'和'd'衝突。 '_'要求回答了這個問題。 – 2012-02-14 20:01:58

回答

5

沒有人有這樣的延伸。只有gcc(也可能是IBM?)有UDL,所以它可能會有一段時間。我希望有些單位將它變成現在開始的tr2。如果發生這種情況,我確信UDL的單位會出現。

這工作:

// ./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; 
} 

我想會不會太硬去通過你喜歡的單位,做到這一點。

關於將它們放入庫中: 字面運算符是命名空間範圍函數。後綴的競爭會變得很難看。我會(如果我是升壓)有

namespace literals 
{ 
... 
} 

然後升壓用戶可以與其他所有使用decls您通常使用沿做

using boost::units::literals; 

。那麼你就不會被std::tr2::units貶損。同樣如果你推出自己的。

+1

煩惱#1:文字操作符只能使用幾個參數類型。這將是很好的版本,返回浮動和雙重以及長雙倍,所以計算不會提升到長雙倍所有時間? ADL不會按返回類型進行選擇 - 特定於精度的名稱空間和使用?啊。 – emsr 2012-02-14 03:55:42

+1

煩惱#2:除了所有的單位,至少有一個公倍數是很好的。例如不僅「m」而且「km」,「cm」,「mm」表示長度,「Hz」,「kHz」,「MHz」,「GHz」表示頻率。它可能變得乏味 - 或者涉及一些宏。 – emsr 2012-02-14 03:59:43

+0

我想知道爲什麼要提高精度_對您來說是一個問題... – celticminstrel 2012-07-07 18:46:23

3

在我看來,在Boost.Units中使用文字沒有太大的收穫,因爲使用現有功能仍然可以實現更強大的語法。

在簡單的情況下,看起來像文字是要走的路,但很快你會發現它不是很強大。例如,您仍然必須爲組合單位定義文字,例如,您如何表達1 m/s(每秒一米)?

目前:

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

但文字?

// 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 

使用現有功能可以實現更好的解決方案。這是我做的:

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; 

你可以做同樣的方式:auto a = 1.*m/pow<2>(s);或者如果你想(如static const area m2 = pow<2>(si::meter);)延長縮寫更

你還要什麼超出了?

也許聯合的解決方案可能是這樣

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

但不會有這麼多的冗餘代碼和增益是最小的(數量後_更換*。)

我的解決方案的一個缺點是它使用常見的一個字母名稱來對名稱空間進行排序。但是除了增加一個下劃線(縮寫的開頭或結尾)外,我沒有看到任何解決方法,如1.*m_/s_,但至少我可以構建真實單位表達式。