2013-07-30 31 views
6

Có cách nào để nhận loại mẫu đệ quy không? Tôi có một vùng chứa mà tôi muốn chỉ định chiến lược lưu trữ cơ bản. Tuy nhiên, khuôn mẫu bên trong phải sử dụng kiểu của khuôn mẫu bên ngoài, do đó nó tạo ra một vòng lặp trong định nghĩa kiểu - mà không thể xác định được.Loại mẫu đệ quy cho chuyển tiếp vùng chứa/tên tệp

Về những gì tôi muốn:

template<typename C> 
struct inner { 
    C * object[16]; 
}; 

template<typename T, typename Inner> 
struct container { 
    T value; 
    Inner<container> holder; 
}; 

C++ 11 giải pháp được sử dụng tốt (mặc dù tôi vẫn còn trên gcc 4.6.3).

+3

Có một cái gì đó gọi là "mẫu đệ quy tò mò" (CRTP)? Có lẽ nó sẽ giúp đỡ, không chắc chắn ... http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern – Jimbo

+0

Các hành vi mới mà kiểu dữ liệu đệ quy này có thể phân biệt nó với một danh sách được liên kết là gì? – abiessu

+0

@abiessu, sử dụng hiện tại của tôi là thực sự cho một cây radix. Mỗi nút có chỉ mục về cách truy cập nút tiếp theo và 'bên trong' là những gì xác định chiến lược cho chỉ mục đó. Tức là, khuôn mẫu cho phép nói rằng trẻ em được quản lý như thế nào, trái với một màu đỏ đen, băm hoặc chiến lược khác cố định. –

Trả lời

5

Bạn cần phải nói với trình biên dịch rằng Inner là một lớp templated:

template<typename T, template<typename> class Inner> 
struct container { 
    T value; 
    Inner<container> holder; 
}; 
+0

Tại sao nó phải là 'lớp' trước Nội bộ? Tôi hiểu nó không phải là một tham số chung nữa, nhưng là một kiểu lớp, mặc dù tôi đã mong đợi 'struct' cũng hoạt động. Vì nó không phải là tôi không chắc tôi khá hiểu. –

+0

@ edA-qamort-ora-y Đó là cách các mẫu hoạt động. Bạn có thể sử dụng từ khóa 'typename' chung hoặc' lớp'. Tuy nhiên trong trường hợp này vì 'Inner' là một lớp mẫu, nó phải được khai báo như là một khuôn mẫu' lớp'. Bạn có thể xác định cấu trúc templated, nhưng không phải bên trong một danh sách đối số mẫu. –

0

Tôi không chắc chắn lý do tại sao bạn đang thêm các mẫu tham số Inner loại, kể từ khi bạn xác định holder là một loại dựa trên Containerinner, cả hai đều có sẵn tại thời điểm bạn tuyên bố chủ sở hữu.

Bạn có định sử dụng bất kỳ loại nào khác ngoài struct inner làm thông số mẫu cho Container không? Nếu không, mã đơn giản sau biên dịch và chạy cho tôi trong VS2010:

#include <vector> 
#include <stdio.h> 

template <typename C> 
struct inner{ 
    C * objects[16]; 
    bool hasobj; 

    inner():hasobj(false){} 
}; 

template <typename T> 
class Container { 
    inner<Container> holder; 
    T value; 
public: 

    Container(const T& valueP){ 
     value = valueP; 
    } 
    void AddChild(Container* rhs){ 
     holder.objects[0] = rhs; //Always using first location, just for example 
     holder.hasobj = true; 
    } 

    void PrintStuff()const{ 
     if(holder.hasobj){ 
      holder.objects[0]->PrintStuff(); 
     } 
     printf("VAL IS %d\n", value); 
    } 
}; 

int main(){ 
    Container<int> c(10); 

    Container<int> c1(20); 
    c1.AddChild(&c); 
    c1.PrintStuff(); 
} 

Về cơ bản, đây là giả định rằng các container luôn xác định holder về inner, giúp thoát khỏi các tham số mẫu thêm, khi xác định Container. Hy vọng điều này sẽ giúp :) arun

+0

Về Inner, vâng, đó là mục đích, bạn có thể chọn loại đang được sử dụng cho lớp bên trong. –