2012-11-02 38 views
5

Có cách nào tốt hơn để thực hiện những việc sau không?So sánh loại mẫu với giá trị số không đổi

Tôi có một lớp vector, với chức năng sau:

template <typename T> 
bool Vector3<T>::IsUnitVector() const 
{ 
    return IsAlmostEqual(this->GetLength(), One<T>::Value()); 
} 

Như T có thể float hay double (Tôi đang sử dụng rõ ràng mẫu instantiation để đảm bảo chỉ những loại được hỗ trợ), tôi đã phải tạo ra một lớp helper, mà trả về giá trị là 1, trong các loại hình chính xác:

template <typename T> 
struct One 
{ 
    static T Value(); 
}; 

template <> 
struct One<int> 
{ 
    static int Value() { return 1; } 
}; 

template <> 
struct One<float> 
{ 
    static float Value() { return 1.0f; } 
}; 

template <> 
struct One<double> 
{ 
    static double Value() { return 1.0; } 
}; 

Đây không phải là quá xấu cho đến khi tôi nhận ra tôi cần phải tạo ra một lớp Zero cũng để so sánh khác. Vì vậy, câu hỏi của tôi là, có cách nào tốt hơn để đạt được điều này? tất cả

+1

Tôi nghĩ điều này rất phổ biến. Bạn đã cố gắng chỉ nói 'return 1;' trong phiên bản không chuyên biệt của 'One '? Tôi nghĩ rằng điều này sẽ làm điều đó nhờ chuyển đổi ngầm định. – leemes

+0

Tôi đã làm, nhưng vì IsAlmostEqual là templated, trình biên dịch không biết loại nào để sử dụng (vì int có thể được chuyển đổi sang float, double etc). –

Trả lời

8
return IsAlmostEqual(this->GetLength(), static_cast<T>(1)); 

nhỏ, giá trị số nguyên không âm nên được chính xác biểu diễn bởi mỗi loại số, vì vậy chỉ đơn giản static_cast 'ing để loại mong muốn nên là đủ.

Ngoài ra, giả sử IsAlmostEqual là một hàm thành viên tĩnh có hai tham số kiểu T (ví dụ như IsAlmostEqual(T lhs, T rhs)), chỉ cần để cho các trình biên dịch thực hiện việc chuyển đổi tự động trong các cuộc gọi chức năng:

return IsAlmostEqual(this->GetLength(), 1); 
+0

Chuyển đổi ngầm không hoạt động, vì tôi nhận được một lỗi T loại mơ hồ từ trình biên dịch. Các static_cast nên làm việc mặc dù! –

+0

Đã chấp nhận câu trả lời - cho đề xuất 'static_cast '. Cảm ơn! –

0

Tại sao không chỉ cho phép trình biên dịch thực hiện công việc chuyển đổi

template<typename T, int val> 
bool Vector3<T>::_isConstant()const{ 
    return IsAlmostEqual(this->GetLength(), val); 
} 

template <typename T> 
bool Vector3<T>::IsUnitVector() const{ 
    return _isConstant<T,1>(); 
} 
template<typename T> 
bool Vector3<T>::IsZeroVector()const{ 
    return _isConstant<T,0>(); 
} 

không chắc chắn cú pháp có đúng hay không, nhưng đó là ý tưởng chung.

0
template <typename T> 
struct Value 
{ 
    static T Zero(); 
    static T One(); 
}; 

template <> 
struct Value<int> 
{ 
    static int Zero() { return 0; } 
    static int One() { return 1; } 
}; 
// .. and so on 
Các vấn đề liên quan