2013-01-28 27 views
5

Tôi có lớp này:Tăng thời gian biên dịch biến với mỗi instantiation của một lớp generic

template <typename T, uint64_t N> 
struct Probe { 
    static const uint64_t Counter = N; 
    typedef T Type; 
}; 

Mà tôi sử dụng như:

typedef Probe <int, 0> FirstIntProbe; 
typedef Probe <int, 1> SecondIntProbe; 
typedef Probe <float, 2> FloatProbe; 

Có thể tạo ra một thời gian biên dịch \ phương pháp vĩ mô cho phép tôi khởi tạo lớp này mà không chỉ định thông số thứ hai như:

typedef Probe <int, Something?> FirstIntProbe; 
typedef Probe <int, Something?> SecondIntProbe; 
typedef Probe <float, Something?> FloatProbe; 

Tôi giả định điều này là không thể, nhưng sau đó một lần nữa tôi đã nhìn thấy mọi người làm những việc trong C + + tôi sẽ không nghĩ là có thể trước đây.


Cập nhật:

  • Nó không phải là cần thiết để tăng một, nó chỉ quan trọng là mỗi đầu dò có nó là số riêng.
  • Không cần thiết phải có số duy nhất trên các tệp .cpp khác nhau \ đơn vị dịch.
+3

Điều quan trọng là giá trị của N bắt đầu bằng 0 và luôn luôn được tuần tự? Và về hành vi của các đơn vị dịch thuật thì sao? Một số trình biên dịch có '__COUNTER__', có thể là đủ cho mục đích của bạn. –

+0

Cập nhật câu hỏi –

Trả lời

7

Bạn có thể nhìn vào cách sử dụng __COUNTER__ vĩ mô, đó là một phần mở rộng trình biên dịch (nhưng được hỗ trợ trên GCCMSVC, trong số những người khác). Lưu ý rằng __COUNTER__ là duy nhất trên mỗi đơn vị dịch, tức là mỗi tệp .cpp.

chỉnh sửa: Bao gồm tiêu đề trong nhiều đơn vị dịch là OK. Ví dụ này liên kết và chạy hoàn toàn tốt đẹp (xây dựng trên GCC 4.5):

probe.h:

template <typename T, int N> 
struct Probe { 
    typedef T Type; 
}; 

#define DECLARE_PROBE(type) typedef struct Probe<type, __COUNTER__> 

main.cpp:

#include "test.h" 

DECLARE_PROBE(int) intprobe; 
DECLARE_PROBE(float) floatprobe; 

int main(int argc, char** argv) { 
    intprobe ip; 
    floatprobe fp; 
    return 0; 
} 

test.cpp:

#include "test.h" 

DECLARE_PROBE(int) intprobe; 
DECLARE_PROBE(float) floatprobe; 

static intprobe ip; 
static floatprobe fp; 
+2

Cách thức hoạt động này có thể? '__COUNTER__' được mở rộng cho mỗi lần sử dụng trong mỗi đơn vị dịch. Vì vậy, nếu 'Probe' nằm trong tiêu đề, và được bao gồm trong nhiều đơn vị chuyển đổi, bạn sẽ có hành vi không xác định, do vi phạm quy tắc một định nghĩa và ngay cả khi' Probe' chỉ xuất hiện trong một đơn vị dịch, '__COUNTER__' là một phần của macro, nó sẽ chỉ được mở rộng một lần. –

+0

Như tôi đã đề cập, '__COUNTER__' chỉ là duy nhất trên mỗi đơn vị dịch. '__COUNTER__' mở rộng tốt trong việc sử dụng macro; thử '#define DECLARE_PROBE (loại) typedef struct Probe ' để biết kích thước. – sheu

+0

Tôi đã chỉnh sửa câu trả lời bằng cách sử dụng ví dụ. Nó hoàn toàn tốt để bao gồm các lớp mẫu và định nghĩa macro trong một tiêu đề chung. – sheu

5

Nó thực sự rất đơn giản nếu bạn không cần một biểu thức không thể tách rời (tức là bạn không sử dụng Counter làm độ mờ của một mảng hoặc như vậy): chỉ cần sử dụng tĩnh toàn cục cho bộ đếm (hoặc đặt nó trong lớp cơ sở không có templated) và tăng mỗi lần bạn sử dụng nó trong khởi tạo. Cái gì như:

int currentProbeCounter; 

template <typename T> 
struct Probe 
{ 
    static int const counter; 
    // ... 
}; 

template <typename T> 
const int Probe<T>::counter = ++ currentProbeCounter; 

Lưu ý rằng điều này sẽ chỉ phân bổ Probe<T>::counter cho một loại nhất định khi (hoặc nếu) bạn sử dụng nó; bạn có thể muốn sử dụng nó trong các nhà thầu của Probe (ngay cả khi bạn không cần) để đảm bảo sự sáng tạo của nó. (Mặt khác, nếu bạn không bao giờ sử dụng nó, những người quan tâm nếu nó không bao giờ được tạo ra.)

+1

Sử dụng biến tĩnh thực tế cho bộ đếm yêu cầu trình biên dịch khởi tạo bộ nhớ (và khởi tạo) cho nó; điều này có thể không thích hợp hơn khi sử dụng tham số mẫu cố định cho bộ đếm, không cần lưu trữ và cho phép trình biên dịch tối ưu hóa và gấp nó thành các biểu thức. – sheu

+0

@sheu Nhưng không có giải pháp nào khác (mà tôi biết) hoạt động. Mọi thứ sử dụng macro đều không thành công ngay sau khi bạn sử dụng nhiều đơn vị dịch. –

+0

Ngoại trừ macro ở trên? – sheu

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