2010-03-04 22 views
5

Có đáng để viết mã như sau để sao chép các phần tử mảng:C++ Lập trình meta với các mẫu so với nội tuyến

#include <iostream> 
using namespace std; 


template<int START, int N> 
struct Repeat { 
    static void copy (int * x, int * y) { 
    x[START+N-1] = y[START+N-1]; 
    Repeat<START, N-1>::copy(x,y); 
    } 
}; 

template<int START> 
struct Repeat<START, 0> { 
    static void copy (int * x, int * y) { 
    x[START] = y[START]; 
    } 
}; 



int main() { 


    int a[10]; 
    int b[10]; 

      // initialize 
    for (int i=0; i<=9; i++) { 
    b[i] = 113 + i; 
    a[i] = 0; 
    } 

      // do the copy (starting at 2, 4 elements) 
    Repeat<2,4>::copy(a,b); 

      // show 
    for (int i=0; i<=9; i++) { 
    cout << a[i] << endl; 
    } 

} //() 

hoặc là nó tốt hơn để sử dụng một chức năng inlined?

Hạn chế đầu tiên là bạn không thể sử dụng các biến trong mẫu.

+2

Bạn chỉ nên sử dụng 'std :: copy'. Bạn có thể gần như chắc chắn rằng * that * sử dụng một số kỹ thuật lập trình meta để chuyển tiếp sao chép giữa các mảng int vào memmove. – UncleBens

+1

Chúa Kitô, tôi muốn dành 10 thời gian sống lập trình prolog, hơn là dành thời gian xem xét thời gian biên dịch lập trình C++: (Nếu bạn phải sao chép một cái gì đó, bạn phải sao chép nó, bạn không thể thoát khỏi nó bằng cách nghĩ rằng bạn có thể làm tại thời điểm biên dịch chỉ vì bạn nghĩ rằng bạn có thể xác định các biến sẽ được sao chép –

+0

@Hassan: Tùy thuộc vào kiểu dữ liệu và căn chỉnh, các chiến lược sao chép khác nhau có thể phù hợp và có thể tăng tốc độ hoạt động một cách đáng kể. không phải là "chỉ là một bản sao". (Nhưng như @ UncleBens nói, 'std :: copy' đã làm điều này) – jalf

Trả lời

8

Điều đó không tốt hơn. Trước hết, nó không thực sự biên dịch thời gian, kể từ khi bạn thực hiện cuộc gọi chức năng ở đây. Nếu bạn may mắn, trình biên dịch sẽ nội tuyến và kết thúc bằng một vòng lặp mà bạn có thể đã viết cho mình với số lượng mã ít hơn nhiều (hoặc chỉ bằng cách sử dụng std::copy).

+3

+1 f * ck yeah! ! – Tom

+2

Điều này không đúng. Các đệ quy là biên dịch-thời gian, không có đệ quy thời gian chạy ở đây. Mỗi hàm là một lớp khác, và không chỉ là hàm giống nhau. Điều gì sẽ nói sẽ là đúng cho Java mặc dù! – PierreBdR

+2

@PierreBdr, đúng là một hàm khác nhau có liên quan mỗi lần. Nhưng đây là những lời gọi hàm được thực hiện trong thời gian chạy, và hiệu quả là nếu bạn gọi hàm giống nhau theo cách đệ quy (trái với * true * biên dịch thời gian đệ quy ala ''static int const value = Class :: value + 1 ; '). Sự khác biệt duy nhất là điều kiện kết thúc có thể được đánh giá tại thời gian biên dịch. Nhưng như vậy có thể điều kiện của một vòng lặp tương đương. –

0

Bạn không nên làm điều này. Các mẫu được phát minh cho các mục đích khác nhau, không phải để tính toán, mặc dù bạn có thể thực hiện nó. Trước tiên, bạn không thể sử dụng biến, mẫu thứ hai sẽ tạo ra các cấu trúc không được sử dụng khi biên dịch và thứ ba là: sử dụng for (int i = start; i <= end; i++) b[i] = a[i];

+1

Có, các mẫu được phát minh cho các mục đích khác nhau, nhưng bạn chỉ không thể tưởng tượng số lượng sách được viết và e-ink được sử dụng cho lần sử dụng thứ hai không có ý định đó! – cibercitizen1

+0

Đúng, không tuyên bố về các mẫu mà bạn không thể chứng minh được. –

1

Quy tắc chung: Sử dụng mẫu cho những thứ được biết tại thời gian biên dịch. Nếu bạn không biết kích thước mảng của bạn tại thời gian biên dịch, thì không sử dụng mẫu cho nó.

0

Điều đó tốt hơn vì bạn kiểm soát và thực thi việc bỏ vòng lặp của chính bạn.

Một vòng lặp có thể được trải ra bởi trình biên dịch tùy thuộc vào tùy chọn tối ưu hóa ...

Việc sao chép với copy là gần như là tốt nhất không phải là một câu trả lời chung tốt vì unrolling vòng lặp có thể được thực hiện bất cứ điều gì là việc tính toán được thực hiện bên trong ...

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