2017-03-06 9 views
2

물리적 특성 단위에 대해 11 개의 사용자 정의 리터럴을 사용하는 방법을 배우려고합니다. 문제는 어떻게 이러한 유닛들의 혼합을 피하는가하는 것입니다. 그렇게 (8.0_kg + 8.0_km) -> 오류가 발생합니다. 어떤 아이디어 야? 나는 C++을 처음 접했습니다.C++ 물리적 특성 단위에 대해 11 개의 사용자 정의 리터럴

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 


} 
+6

그냥'long double' 대신 ('struct' /'class') 타입으로 만들 것입니다. – NathanOliver

+0

[strong typedef] (http://stackoverflow.com/questions/28916627/strong)에서보실 수 있습니다. -typedefs)를 입력하십시오. – Jarod42

답변

2

다른 단위의 숫자 값을 나타내는 클래스를 만듭니다. 즉, 숫자와 단위 :

의 일반적인 순서 http://en.cppreference.com/w/cpp/language/user_literal

class MassKg 
{ 
    double value; 

    // public c'tor, numeric operators, &c. 
}; 

// ... 

MassKg mass(5.0); 
DistanceM distance(3.0); 
auto c = mass * distance; // may yield an instance of TorqueKgM, or MomentumKgM, therefore 
// explicit functions/methods are preferrable for mixed 
// multiplication or division 
auto mass2 = mass + MassKg(2.0); // yiels an instance of MassKg 
auto invalid = mass + distance; // compile time error 
+0

예를 들어, 난 그냥이 http://en.cppreference.com/w/cpp/language/user_literal을 남겨주세요 – jamek

+0

@ Jarod42 더 좋았어요. 변수 이름, 감사합니다 ^^ – yeoman

+0

더 나은 방법은, 나는 의미합니다 .- 바보 같은 자동 고침. – yeoman

6
참조를 유지하는 데 도움이 있기 때문에,하지만, ++ (11)

사용자 정의 리터럴 인스턴스를 읽기 쉽게 만들 수 있습니다 C 오래 전에 이후 해본 적이 방법

원시 타입을 제한 할 수 없기 때문에 자신 만의 유형을 정의해야합니다.

"태그가있는 템플릿"을 반복적으로 사용하지 않고 유형을 안전하게 유지할 수 있습니다.
이것은 확장 될 수 있으므로 예를 들어 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 
} 

1) 나는 C++에서 설립 된 용어는 없다고 생각하지만 하스켈은 phantom types 등을 말한다 것과 매우 유사하다.