2011-12-10 33 views
5

tôi có thể làm gì để làm cho công việc này:Mẫu tự tham khảo trong Template Đối số

template<class C, class V, Test V::*> 
class Test { 
}; 

nó mang lại cho tôi lỗi biên dịch:

unknown type name 'Test' 

Đó là một mẫu tự tham khảo cho bây giờ, mà doesn dường như không thể. Những gì có thể có thể được thực hiện để làm cho nó hoạt động?

CHỈNH SỬA:

Đây là những gì tôi cần. Tôi muốn thực hiện một lược đồ quan hệ hai chiều (nghĩ cha-con) với nỗ lực mã hóa tối thiểu.

template <class O, class T, Reference<T, O, Reference O::*> T::* opposite> 
class Reference 
{ 
    T **data; 
    int count; 
public: 
    Reference(): data(new T*[N]), count(0) {} 
    ~Reference() {delete[] data;} 
    Reference &add(T *t) { 
     handleOtherSide(); 
     return link(t); 
    } 
    // a lot of stuff to implement this 
}; 

Đó là lớp thu thập. Dưới đây là làm thế nào nó sẽ được sử dụng:

class Partner 
{ 
public: 
    Reference<Partner, Address, &Address::partner> addresses; 
}; 

class Address 
{ 
public: 
    Reference<Address, Partner, &Partner::addresses> partner; 
}; 

Mục tiêu của tôi là phải có tất cả mọi thứ cần thiết cho việc tham khảo để làm việc được cung cấp như mẫu đối số, do đó không có nhu cầu để cung cấp nhà xây dựng cho các lớp học như đối tác và địa chỉ (hiện tại tôi cung cấp con trỏ thành viên đối diện như một hàm tạo arg nhưng điều này đòi hỏi tôi phải có các hàm tạo rõ ràng cho các lớp người tham gia). Tôi cũng cần phải chuyển vào hoặc tính toán con trỏ "chủ sở hữu" cho lớp Tham chiếu. Tôi đã để lại vấn đề này ở đây vì tôi muốn tập trung vào khía cạnh khuôn mẫu tự tham chiếu.

Cách dễ nhất để nghĩ về điều này là tăng :: bimap. Nhưng vấn đề với bimap là tôi không muốn bimap kèm theo nhưng chỉ là phần bên trái và bên phải của nó. bimap cũng không khả thi vì nó sẽ dẫn đến một bimap duy nhất quản lý tất cả các mối quan hệ của một mối quan hệ cụ thể. Nó sẽ có thể chứa một số lượng lớn các đối tượng làm chậm hoạt động trên nó.

+2

Điều này là để làm gì? Nó có thể đơn giản hơn nhiều để thực hiện điều này một số cách khác hơn là tự tham khảo. – Jon

+5

Tôi đã phải upvote câu hỏi này để có được OP off số danh tiếng 666 của mình. –

+2

Mục tiêu mà bạn đang cố gắng đạt được với một mẫu đệ quy như thế nào, nếu bạn không ngại tôi hỏi? – dasblinkenlight

Trả lời

1

Vấn đề là, những gì tôi muốn đạt được là không thể trong C++, ít nhất là không phải với các mẫu và số lượng mã và các lớp học tôi nhằm (đọc: dòng mã cho mỗi thành viên). Nó bắt đầu với trình biên dịch cần các khai báo chuyển tiếp và các kiểu được định nghĩa đầy đủ, đó là làm cho các thành viên có giá trị và các đối số mẫu của không thể như vậy (trong trường hợp các phụ thuộc tuần hoàn). Sau đó, không thể có một con trỏ thành viên như là một khuôn mẫu arg khi lớp của thành viên đó chưa được định nghĩa đầy đủ. Nguyên nhân gốc rễ của tất cả điều này là làm thế nào trình biên dịch hoạt động: nó là duy nhất vượt qua. Và không có gì tôi có thể làm về điều đó.

Giải pháp là sử dụng các thành viên tham chiếu hoặc lớp cơ sở kiểu OO hoặc tăng cường :: bất kỳ vùng chứa kiểu nào để tránh các mẫu. Với 2 sau, có thể có các thành viên có giá trị.

2

Bạn đang tìm kiếm một cái gì đó như thế này? Nó không phải tự tham khảo mẫu, nhưng bạn có thể chỉ định lớp được thừa kế như một kiểu mẫu cho lớp cơ sở và lớp cơ sở có thể gọi các phương thức có nguồn gốc v.v .:

template< typename PType, typename PDerived > 
class TBase 
{ 
    //do stuff with TDerived 
public: 
    bool foo(void) 
    { 
    return (static_cast< PDerived* > (this)->bar()); 
    } 
}; 

template< typename PType > 
class TDerived : public TBase< PType, TDerived<PType> > 
{ 
    friend class TBase< PType, TDerived<PType> > ; 
    //do stuff 
protected: 
    bool bar(void) 
    { 
    return (true); 
    } 
}; 

EDIT: Một lần nữa, tôi không chắc chắn những gì cuối cùng của bạn là mục tiêu. Đây là một giải pháp cho những gì tôi nghĩ rằng bạn muốn, hoặc, ít nhất, một số gợi ý cho những gì bạn có thể sử dụng để thực hiện thiết kế của bạn. Yêu cầu duy nhất mà tôi đặt là cả hai TAddressTPartner có chức năng có cùng tên. Xem nếu đó là những gì bạn cần. Về nguyên tắc, bạn có thể tạo một lớp trợ giúp và sử dụng CRTP để truy cập chức năng thành viên thông qua một con trỏ, nhưng tôi không nghĩ bạn thực sự cần nó.

template< typename PType1, typename PType2 > 
class TReference 
{ 
public: 
    int mFlag; 

    TReference() : 
    mFlag(0) 
    { 
    } 
    TReference(int fFlag) : 
    mFlag(fFlag) 
    { 
    std::cout << "Creating reference " << PType1::sName << " -> " << PType2::sName << "." << std::endl; 
    } 
    TReference< PType2, PType1 > AccessOpposite(void) 
    { 
    PType2 lTmp; 
    lTmp.Opposite(); 

    return TReference< PType2, PType1 > (-1); 
    } 
}; 

class TPartner; 

class TAddress 
{ 
public: 
    static const char* sName; 
    TReference< TAddress, TPartner > mRef; 

    void Opposite(void) 
    { 
    std::cout << sName << "::Opposite" << std::endl; 
    } 
}; 

class TPartner 
{ 
public: 
    static const char* sName; 
    TReference< TPartner, TAddress > mRef; 

    TReference< TAddress, TPartner > Opposite(void) 
    { 
    std::cout << sName << "::Opposite" << std::endl; 
    } 
}; 

const char* TAddress::sName = "TAddress"; 
const char* TPartner::sName = "TPartner"; 

int main(void) 
{ 
TAddress lAddress; 
TPartner lPartner; 

std::cout << lAddress.mRef.mFlag << " " << lPartner.mRef.mFlag << std::endl; 

lPartner.mRef = lAddress.mRef.AccessOpposite(); 

std::cout << lAddress.mRef.mFlag << " " << lPartner.mRef.mFlag << std::endl; 

return (0); 
} 
+0

Điều đó có vẻ khá thú vị và hài hước. Có ok không khai báo thanh thành viên() ở cấp cơ sở? –

+0

Có, nó là ok do cách chức năng mẫu được khởi tạo. 'foo' sẽ không được khởi tạo cho đến khi nó thực sự được gọi trong mã và bởi thời gian đó' TDerived' đã được xác định. Tìm kiếm CRTP để biết thêm thông tin. – lapk

+0

Sau khi xem xét điều này trong một vài ngày tôi phải nói làm thế nào điều này có thể giải quyết vấn đề của tôi là ngoài tôi. Có lẽ bạn có thể áp dụng ví dụ của tôi nhiều hơn một chút để tôi có thể xem giải pháp? –

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