2012-01-14 40 views
6

Có một thủ thuật tinh vi cho chuyên môn hóa mẫu để tôi có thể áp dụng một chuyên môn cho basic POD (khi tôi nói POD cơ bản tôi không đặc biệt muốn cấu trúc POD (nhưng tôi sẽ thực hiện)).Chuyên môn mẫu cho POD cơ bản chỉ

template<typename T> 
struct DoStuff 
{ 
    void operator()() { std::cout << "Generic\n";} 
}; 
template<> 
struct DoStuff</*SOme Magic*/> 
{ 
    void operator()() { std::cout << "POD Type\n";} 
}; 

Hoặc tôi có phải viết chuyên môn cho từng loại được cài sẵn không?

template<typename T> 
struct DoStuff 
{ 
    void operator()() { std::cout << "Generic\n";} 
}; 


// Repeat the following template for each of 
// unsigned long long, unsigned long, unsigned int, unsigned short, unsigned char 
//   long long,   long,   int,   short, signed char 
// long double, double, float, bool 
// Did I forget anything? 
// 
// Is char covered by unsigned/signed char or do I need a specialization for that? 
template<> 
struct DoStuff<int> 
{ 
    void operator()() { std::cout << "POD Type\n";} 
}; 

Kiểm tra đơn vị.

int main() 
{ 
    DoStuff<int>   intStuff; 
    intStuff();   // Print POD Type 


    DoStuff<std::string> strStuff; 
    strStuff();   // Print Generic 
} 
+0

Ok, tôi tò mò - Bạn muốn làm gì nếu "công cụ" bạn muốn thực hiện việc triển khai chưa thực hiện khác với các loại POD? –

+0

Tôi đang sử dụng boost :: mpl. Đối với lớp như các đối tượng, tôi cần phải đăng ký một hành động thao túng đối tượng lớp (và đăng ký hành động cho tất cả các thành viên của nó). Đối với các đối tượng POD bình thường, tôi có một hành động đơn giản hơn nhiều sẽ được đăng ký để thực hiện hành động trên đối tượng. –

Trả lời

6

Nếu bạn thực sự muốn loại chỉ cơ bản và không dùng định nghĩa loại POD sau đó những điều sau đây nên làm việc:

#include <iostream> 
#include <boost/type_traits/integral_constant.hpp> 
#include <boost/type_traits/is_fundamental.hpp> 
#include <boost/type_traits/is_same.hpp> 

template<typename T> 
struct non_void_fundamental : boost::integral_constant< 
    bool, 
    boost::is_fundamental<T>::value && !boost::is_same<T, void>::value 
> 
{ }; 

template<typename T, bool Enable = non_void_fundamental<T>::value> 
struct DoStuff 
{ 
    void operator()() { std::cout << "Generic\n"; } const 
}; 

template<> 
struct DoStuff<T, true> 
{ 
    void operator()() { std::cout << "POD Type\n"; } const 
}; 

Nếu bạn cũng muốn loại POD người dùng định nghĩa, sau đó sử dụng boost::is_pod<> thay vì non_void_fundamental<> (và nếu bạn đang sử dụng C++ 11 và làm điều này cho các mục đích tối ưu hóa, sử dụng std::is_trivially_copyable<> thay thế).

1

Tăng cường có boost::is_pod. Đó là những gì bạn đang tìm kiếm?

(Tôi chưa bao giờ sử dụng nó, vì vậy tôi sẽ không gây rắc rối cho bản thân mình bằng cách cố gắng để xây dựng mã chính xác mà bạn yêu cầu ví dụ của bạn.)

+1

C++ 11 cũng có điều này. –

6

Trong C++ 11, nhiều đặc điểm đã được thêm vào thư viện chuẩn, và hầu hết có vẻ đặc biệt nhằm vào các chuyên môn thú vị (và đặc biệt là thao tác bitwise).

Các đặc điểm cấp cao nhất bạn có thể quan tâm là std::is_trivial, tuy nhiên có nhiều người khác:

  • std::is_trivially_default_constructible
  • std::is_trivially_copy_constructible
  • std::is_trivially_move_constructible
  • std::is_trivially_copyable (có thể được sao chép qua memcpy)

Nói chung, tiêu chuẩn đã cố gắng để có được các đặc điểm hạt mịn hơn có thể, do đó bạn không cần dựa vào các giả định rộng như is_pod mà thay vào đó tinh chỉnh các ràng buộc của bạn để phù hợp với những gì các phương pháp của bạn thực sự cần.

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