2012-06-18 43 views
8

Tôi đang cố tìm một giải pháp để có các hằng số số liên tục bên trong phương thức lớp mẫu. Tôi đang thực hiện một số lớp mẫu toán học được sử dụng với các loại float hoặc double. Vấn đề là các literals khác nhau tùy thuộc vào kiểu dữ liệu (ví dụ "0.5f" cho float và "0.5" cho double). Cho đến nay, tôi đưa ra hai giải pháp. Một số mã giả thuyết cho mã đầu tiên:Chức năng chuyên môn trong lớp mẫu cho các ký tự float và double

template <typename T> 
class SomeClass 
{ 
    public: 
     T doSomething(T x); 
}; 

template <> 
float SomeClass<float>::doSomething(float x) 
{ 
    float y = 0.5f; 
    /* 
    * Do computations... 
    */ 
    return x; 
} 

template <> 
double SomeClass<double>::doSomething(double x) 
{ 
    double y = 0.5; 
    /* 
    * Do computations... 
    */ 
    return x; 
} 

Phương pháp trên ghi đè toàn bộ phương pháp cho mọi loại được sử dụng.

cách tiếp cận khác:

template <typename T> 
class SomeClass 
{ 
    public: 
     T doSomething(T x); 

    private: 
     T getValue(); 
}; 

template <typename T> 
T SomeClass<T>::doSomething(T x) 
{ 
    T y = getValue(); 
    /* 
    * Do computations... 
    */ 
    return x; 
} 

template <> 
float SomeClass<float>::getValue() 
{ 
    return 0.5f; 
} 

template <> 
double SomeClass<double>::getValue() 
{ 
    return 0.5; 
} 

Cái này không đòi hỏi phải viết cùng phương pháp nhiều lần cho loại hình cụ thể, nhưng đòi hỏi phải có nhiều getValue() phương pháp cho mỗi "con số kỳ diệu" mà cần phải được được sử dụng bên trong phương thức.

Có cách nào khác, "thanh lịch hơn" để giải quyết vấn đề này không?

+1

Nếu chỉ về chữ, tôi nghĩ bạn có thể sử dụng đúc static_cast () – Mohammad

+0

Tôi đã không đề cập đến nó trong câu hỏi của mình, nhưng tôi muốn tránh mọi chuyển đổi, không rõ ràng hoặc ngầm. – umebe

Trả lời

0

Bạn không cần phải lo lắng về điều này - hãy sử dụng 0,5 và nếu loại đó nổi thì trình biên dịch sẽ vẫn khởi tạo nó tối ưu với cùng giá trị như khi bạn sử dụng 0.5f.

Đó là một chút dài dòng, nhưng bạn có thể muốn đọc qua "cơ chế khác hỗ trợ đa hình" một phần của câu trả lời của tôi ở đây: Polymorphism in c++

Đối với việc sử dụng tổng quát hơn của hằng số float khắp các chức năng - đặc biệt là ở so sánh và biểu thức - giá trị đọc liên kết bluemess đề cập bên dưới ....

+0

Giả sử rằng tôi sẽ sử dụng chữ "0,5". Điều đó sẽ không gây ra chuyển đổi ẩn (runtime?) Để trôi nổi tại một số điểm? Trong ví dụ tôi cho nó có thể không quan trọng, nhưng nói chung tôi thà tránh chuyển đổi. – umebe

+1

Nó sẽ là một chuyển đổi thời gian biên dịch. –

+0

Tôi đã thấy rằng việc sử dụng chữ "0,5" cho float trong một số trường hợp sẽ dẫn đến nhiều chuyển đổi được giải thích ở đây: [Chúng ta có nên sử dụng các chữ nổi cho float thay vì các chữ kép đơn giản hơn không?] (Http://stackoverflow.com/a/7662804/1464168) – umebe

0

Giả sử nó thực sự cần thiết để sử dụng các giá trị khác nhau trong hai chuyên ngành (không cần thiết cho 0,5 và 0,5f). ít đánh máy để làm:

template <typename T> 
class SomeClass 
{ 
    public: 
    T doSomething(T x); 

    private: 
    static const T magic_number_1; 
}; 

template <typename T> 
T SomeClass<T>::doSomething(T x) 
{ 
    T y = magic_number_1; 
    /* 
    * Do computations... 
    */ 
    return x; 
} 

template <> 
const float SomeClass<float>::magic_number_1 = 0.5f; 

template <> 
const double SomeClass<double>::magic_number_1 = 0.5; 
+0

Phải, điều này có vẻ tốt hơn là các phương thức getValue() riêng biệt. – umebe

1

Cảm ơn tất cả các bạn đã trả lời và nhận xét. Tôi cho phép bản thân mình để tóm tắt những gì đã được nói cho đến nay và thêm kết luận của tôi.

Tôi sẽ triển khai một số mẫu lớp toán học để được khởi tạo để sử dụng với kiểu float hoặc double. Có một nhu cầu sử dụng một số chữ số trong nội bộ trong lớp. Chúng sẽ là một số các hằng số và hằng số được sử dụng phổ biến, chẳng hạn như 0.0, 0.5, 1.0, pi, v.v. Tôi đang tìm một giải pháp để làm cho lớp instantiation hoạt động trên các chữ khác nhau tùy thuộc vào loại của nó.

Có hay không sử dụng các chữ nổi và kép?

Nói hơi đi về chủ đề có hay không bận tâm sử dụng các chữ cái riêng biệt cho float và double. Điều này có thể do một ví dụ không may chút nào tôi đưa ra trong câu hỏi của mình. Trong ví dụ, chữ sẽ được chuyển đổi thành kiểu thích hợp tại thời gian biên dịch, vì vậy không có hại gì được thực hiện. Nhưng nói chung sẽ có trường hợp nhu cầu đen được sử dụng trong biểu hiện, ví dụ:

float foo(float x) 
{ 
    return x * 3.14; 
} 

Điều này sẽ buộc trình biên dịch để chuyển đổi x tăng gấp đôi, làm cho tính toán, sau đó chuyển đổi kết quả lại nổi. Ưu điểm và nhược điểm của hành vi như vậy:

Ưu điểm:

  • chính xác tăng vì tính thực tế sẽ được thực hiện trong đôi chính xác.

Nhược điểm:

  • Nếu hiệu suất là một vấn đề, điều này có thể dẫn đến thực hiện nhanh hơn cũng như chậm hơn, tùy thuộc vào môi trường và nền tảng. Điều này giới thiệu một số thay đổi hiệu suất tùy thuộc vào việc triển khai, trong đó là xa như tôi được coi là xấu.
  • Giới thiệu tính toán không nhất quán vì một số thao tác sẽ được thực hiện trên trên phao và một số hoạt động tăng gấp đôi, tùy thuộc vào việc sử dụng chữ. Điều này cũng có thể mở một số lỗi tiếp xúc.
  • Nó phá vỡ ý tưởng chuyên lớp cho nổi ở nơi đầu tiên vì tính toán nội bộ sẽ được thực hiện trên đôi anyway.

Tóm lại, mục đích là làm cho lớp học hoạt động trên các loại thích hợp mà không cần bất kỳ chuyển đổi bổ sung nào. Ý tưởng sử dụng các loại chữ kép ở mọi nơi, chẳng hạn như 0,5 và để xử lý chuyển đổi thích hợp thành trình biên dịch không phải là một tùy chọn.

Thông tin thêm về đề tài này: Should we generally use float literals for floats instead of the simpler double literals?

giải pháp có thể?

  • Phương pháp chuyên dùng cho mọi loại bản mẫu hóa tại nơi sử dụng literals. Đây có lẽ là giải pháp tồi tệ nhất bởi vì nó lực lượng để viết cùng một mã hai lần với những thay đổi nhỏ cho các số .
  • Thực hiện các phương thức chuyên ngành getValue<type>() hoặc Jonathan Wakely posted - chuyên biệt thành viên. Điều này có thể dẫn đến việc có một số thành viên hoặc phương pháp có tên ngớ ngẩn trong lớp học, chẳng hạn như getZeroPointFive<float>().
  • Mohammad và Tony Delroy chỉ ra rằng gói mỗi chữ với static_cast<T>() sẽ thực hiện thủ thuật. Chuyển đổi sang loại thích hợp sẽ được thực hiện tại thời gian biên dịch.
+0

Một giải pháp tốt hơn đã đưa ra ... bình luận từ Mohammad ... đúc các giá trị trước khi chúng tham gia vào các biểu thức ala static_cast (5.0).Tôi biết bạn không thích nó, nhưng nó sẽ là thời gian biên dịch và được bản địa hóa với số, trong khi getZeroPointFive v.v. –

+0

Cảm ơn bạn đã chỉ ra điều đó. Tôi đã thêm nó vào các giải pháp khả thi – umebe

Các vấn đề liên quan