C++ c++;11物理属性单位的用户定义文字

C++ c++;11物理属性单位的用户定义文字,c++,user-defined-literals,C++,User Defined Literals,我试图学习如何使用c++11用户定义的文字作为物理属性的单位。问题是,如何避免这些单元的混合。因此(8.0_kg+8.0_km)-->给出了误差。有什么想法吗,伙计们?我是C++新手,和蔼可亲。 class Mass{ public: //Mass(){ // cout << "only Mass units allowed in here" << endl; //} //~Ma

我试图学习如何使用c++11用户定义的文字作为物理属性的单位。问题是,如何避免这些单元的混合。因此(8.0_kg+8.0_km)-->给出了误差。有什么想法吗,伙计们?我是C++新手,和蔼可亲。
class Mass{
    public:        
        //Mass(){
        //    cout << "only Mass units allowed in here" << endl;
        //}
        //~Mass();
        long double getWeight(long double a);        
        double car, house, cat;

    private:
        long double a;


    };


long double Mass::getWeight(long double w) {

    cout << "returning argument: " << w << '\n'<< endl;
    return 0;
}


long double operator"" _km(long double d) { return d * 1000.0; }
long double operator"" _m (long double d) {return d;}
long double operator"" _cm(long double d) { return d / 100.0; }

long double operator"" _tonne(long double m) { return m * 1000.0 ; }
long double operator"" _kg(long double m) { return m ; }
long double operator"" _lb(long double m) { return m * 0.453592; }

long double getDistance(long double d){
    long double starting_d = 61.0_kg;
    long double total_d = d + starting_d;
    cout << "the distance I have run is: " << total_d << endl;
    return 0;
}

int main() {


    cout <<  6.0_km << endl;
    cout <<  6.0_km + 3.0_m << endl;
    cout <<  6.0_km + 3.0_m + 15.0_cm << '\n' << endl;

    cout <<  8.0_tonne << endl;
    cout <<  8.0_km + 4.0_kg << endl;
    cout <<  8.0_km + 4.0_kg + 21.0_lb << '\n' << endl;


    long double distance = 5.45_km;
    getDistance(distance);

    Mass obj1;
    obj1.getWeight(13.96_lb);

    cout << "This is clearly wrong:  "<<  8.0_km + 4.0_kg << endl;

    obj1.getWeight(10.96_km); // so is this


}
类质量{
公众:
//质量(){

//couth创建表示不同单元的数值的类。这是在C++ 11。 不过,自定义文字可以使实例化更具可读性,因为它有助于保持通常的数字和单位顺序:)


您需要定义自己的类型,因为您不能限制原语所表示的内容

您可以使用“标记模板”1来避免运算符等的重复,并确保其类型安全。
这可以扩展,以便您得到编译器检查的例如
distance*distance=area
speed*time=distance

下面是一个简短的例子:

template<typename Kind>
struct Value
{
    long double value;
    Value& operator+= (Value v) { value += v.value; return *this; }
};

template <typename Kind>
Value<Kind> operator+ (Value<Kind> lhs, Value<Kind> rhs) { return lhs += rhs; }

// These types don't need definitions; we only need some unique type names.
struct M;
struct D;

using Mass = Value<M>;
using Distance = Value<D>;

Mass operator"" _kg(long double d) { return { d };}
Mass operator"" _lb(long double d) { return { d * 0.453592 };}

Distance operator"" _km(long double d) { return { d * 1000 };}
Distance operator"" _mile(long double d) { return { d * 1609 };}

int main()
{
    // OK
    Distance d = 1.2_km + 0.2_mile;
    // OK
    Mass m = 2.3_kg + 1.4_lb;      
    // invalid operands to binary expression ('Distance' (aka 'Value<D>')
    // and 'Mass' (aka 'Value<M>'))
    Distance d2 = 2.4_km + 1.2_kg; // Nope
}
模板
结构值
{
长双值;
Value&operator+=(Value v){Value+=v.Value;返回*this;}
};
模板
值运算符+(值lhs,值rhs){返回lhs+=rhs;}
//这些类型不需要定义;我们只需要一些唯一的类型名。
结构M;
结构D;
使用质量=值;
使用距离=值;
质量运算符“”_kg(长双d){return{d};}
质量运算符“”_lb(长双d){return{d*0.453592};}
距离运算符“”_km(长双d){return{d*1000};}
距离运算符“”_英里(长双d){return{d*1609};}
int main()
{
//嗯
距离d=1.2公里+0.2英里;
//嗯
质量m=2.3_kg+1.4_lb;
//二进制表达式的操作数无效('Distance'(也称为'Value'))
//和“质量”(也称为“值”)
距离d2=2.4公里+1.2公斤;//否
}


< P > 1)我认为C++中没有一个已建立的术语,但它与Haskell的用法很相似。

我会通过使它们成为类型来实现(<代码>结构> <代码> />代码>类<代码>),而不是仅仅是代码> long double <代码>,你可以查看你的质量/长度。
template<typename Kind>
struct Value
{
    long double value;
    Value& operator+= (Value v) { value += v.value; return *this; }
};

template <typename Kind>
Value<Kind> operator+ (Value<Kind> lhs, Value<Kind> rhs) { return lhs += rhs; }

// These types don't need definitions; we only need some unique type names.
struct M;
struct D;

using Mass = Value<M>;
using Distance = Value<D>;

Mass operator"" _kg(long double d) { return { d };}
Mass operator"" _lb(long double d) { return { d * 0.453592 };}

Distance operator"" _km(long double d) { return { d * 1000 };}
Distance operator"" _mile(long double d) { return { d * 1609 };}

int main()
{
    // OK
    Distance d = 1.2_km + 0.2_mile;
    // OK
    Mass m = 2.3_kg + 1.4_lb;      
    // invalid operands to binary expression ('Distance' (aka 'Value<D>')
    // and 'Mass' (aka 'Value<M>'))
    Distance d2 = 2.4_km + 1.2_kg; // Nope
}