如何使用C 11風格的強大的typedef建立一個新的基本型別?
在Nim中編譯,因為編譯器捕獲變數e和d
有不同的型別(錯誤:型別不匹配:got(歐元,浮動))儘管
兩者都是二進位制的浮點數:
type Euros = distinct float when isMainModule: var e = Euros(12.34) d = 23.3 echo (e + d)
在C中執行此操作的一種方法是為浮動類編寫一個包裝類.但
這對於匯出型別的API不起作用,因為大小不會
與浮動一樣.或者即使類的大小與a的儲存長度相匹配
float,它將永遠不會匹配char型別的大小.如果您還實現了所有可能的操作符,例如加法,減法等操作,但是需要很多鍵入和複製程式碼,這將會起作用.
Creating a new primitive
有一個接受的答案,使用boost的強大的typedef.但是typedef
似乎只適用於函式型別簽名,typedef不會阻止兩個
float-inherited型別要一起新增,其型別完全改變
(嗯,因為只有一種新型的錯覺):
#include <boost/serialization/strong_typedef.hpp> #include <stdio.h> BOOST_STRONG_TYPEDEF(float, money); void test(money a, float b) { int t = a + b; printf("value is %d", t); } int main() { money a(5.5); int euros(5); // This is not caught! int dollars = a + euros; printf("dollars %d\n", dollars); // But the compiler catches this misuse. test(euros, a); }
但是幾乎是這樣,由於簽名,test()呼叫將不起作用
不匹配,但語言仍然允許其他操作來處理型別
隨意.
同樣的答案提到C 0x帶來強大的typedef,所以我尋找這個
大約二十一點,他開始談論這些新的強大的typedefs.如果你
僅下載幻燈片,第19頁開始談論SI單位和更晚
第22和23頁提到如何做到這一點.但是,我一直無法
使示例工作.這是我設法制作的拼湊:
template<int M, int K, int S> struct Unit { // a unit in the MKS system enum { m=M, kg=K, s=S }; }; template<typename Unit> // a magnitude with a unit struct Value { double val; // the magnitude explicit Value(double d) : val(d) {} // construct a Value from a double }; using Meter = Unit<1,0,0>; // unit: meter using Second = Unit<0,0,1>; // unit: sec using Speed = Value< Unit<1,0,-1> >; // meters/second type constexpr Value<Second> operator "" _s(long double d) // a f-p literal suffixed by ‘_s’ { return Value<Second> (d); } constexpr Value<Meter> operator "" _m(long double d) // a f-p literal suffixed by ‘_m’ { return Value<Meter> (d); } int main(void) { Speed sp1 = 100_m / 9.8_s; return 42; }
我正在使用最新的Xcode 5.1.1使用命令列在MacOSX下進行編譯:
$g++ unit.cpp -std=c++11 unit.cpp:13:25: error: constexpr function's return type 'Value<Second>' is not a literal type constexpr Value<Second> operator "" _s(long double d) ^ unit.cpp:5:8: note: 'Value<Unit<0, 0, 1> >' is not literal because it is not an aggregate and has no constexpr constructors other than copy or move constructors struct Value { ^ unit.cpp:18:24: error: constexpr function's return type 'Value<Meter>' is not a literal type constexpr Value<Meter> operator "" _m(long double d) ^ unit.cpp:5:8: note: 'Value<Unit<1, 0, 0> >' is not literal because it is not an aggregate and has no constexpr constructors other than copy or move constructors struct Value { ^ unit.cpp:26:20: error: no matching literal operator for call to 'operator "" _m' with argument of type 'unsigned long long' or 'const char *', and no matching literal operator template Speed sp1 = 100_m / 9.8_s; ^ unit.cpp:26:28: error: no matching literal operator for call to 'operator "" _s' with argument of type 'long double' or 'const char *', and no matching literal operator template Speed sp1 = 100_m / 9.8_s; ^ 4 errors generated.
也許幻燈片中給出的例子,我還缺少一些程式碼?有人有一個完整的例子,Bjarne試圖展示嗎?