2009-11-27 41 views
17
  1. Có tương đương với <? extends T>, <? super T> bằng C++ không?Có tương đương với <? extends T>, <? super T> bằng C++ không?

  2. Đồng thời, <? extends T>, <? super T> có hoạt động ngay cả khi T là giao diện trong Java không?

+0

nào bạn cần cái này cái gì? Có thể có một giải pháp đơn giản hơn, giống C++ hơn là cố gắng mô phỏng tính năng Java này – jalf

Trả lời

2

câu trả lời cho phần đầu tiên: Restrict Template Function

JesperE có câu trả lời đúng cho phần 2.

+0

Theo quy tắc rằng nếu lớp được truyền làm đối số có các phương thức cần thiết được xác định là kiểm tra chống lừa đảo. Lớp học được phê duyệt chắc chắn sẽ có tất cả các chức năng cần thiết. Nhưng điều ngược lại không phải lúc nào cũng đúng. Nếu bạn có một cái gì đó như <? mở rộng T> sau đó nó là fool-proof bởi vì chúng tôi xác định rõ ràng phân cấp lớp – user855

+0

@ajay: Nếu bạn muốn hạn chế tham số kiểu là lớp cơ sở vì bạn sử dụng chính xác giao diện lớp cơ sở, thì bạn có cần làm cho nó bản mẫu? Bạn có thể hoạt động trên một lớp cơ sở bằng cách tham chiếu? Điều này sẽ giúp bạn có được sự an toàn kiểu mà bạn đang tìm kiếm. Mẫu cho phép bạn xác định các hoạt động hoạt động trên các loại không nhất thiết phải từ cùng một hệ thống phân cấp. Đó là sức mạnh của họ. Nếu điều này không khả thi trong hoàn cảnh của bạn, có lẽ bạn có thể cập nhật câu hỏi với nhiều chi tiết hơn về những gì bạn đang cố gắng làm và những tính năng nào của C++ có thể giúp bạn đạt được điều đó. –

+0

? mở rộng có nghĩa là bất kỳ lớp con nào của loại cơ sở. – TofuBeer

5

Để trả lời câu hỏi thứ hai của bạn: có. Theo như generics có liên quan, các giao diện được xử lý giống như các lớp thực.

Tôi sẽ để lại câu hỏi đầu tiên cho nhiều người C++ - hiểu biết hơn.

12

Nó không có đường cú pháp khá tốt như trong Java nhưng nó có thể quản lý tốt với boost/type_traits. Xem http://www.boost.org/doc/libs/1_40_0/libs/type_traits/doc/html/index.html để biết thêm thông tin.

#include <boost/type_traits.hpp> 
#include <boost/static_assert.hpp> 

class Base {}; 
class Derived_from_Base : public Base {}; 
class Not_derived_from_Base {}; 

template<typename BASE, typename DERIVED> 
void workOnBase() 
{ 
    BOOST_STATIC_ASSERT((boost::is_base_of<BASE, DERIVED>::value)); 
} 

int main() 
{ 
    workOnBase<Base, Derived_from_Base>();  // OK 
    workOnBase<Base, Not_derived_from_Base>(); // FAIL 
    return 0; 
} 

1> d: ... \ main.cpp (11): lỗi C2027: sử dụng các loại không xác định 'boost :: STATIC_ASSERTION_FAILURE' 1> với 1> [ 1> x = false 1>]

3

Bạn có thể hạn chế phạm vi của thông số mẫu trong C++ bằng cách sử dụng các cơ chế đặc điểm khác nhau, trong đó có các triển khai có sẵn trong tăng cường.

Thông thường bạn không - lý do cú pháp tồn tại trong Java và C# là chúng sử dụng Generics, không phải mẫu.

Generics Java tạo mã dùng chung sử dụng công văn ảo từ loại cơ sở, thay vì tạo mã cho từng loại được sử dụng làm đối số mẫu. Vì vậy, thông thường bạn đang sử dụng hạn chế để cho phép bạn gọi các phương thức trên các đối tượng thuộc loại được sử dụng làm tham số mẫu.

Khi C++ tạo mã cho từng loại được sử dụng làm thông số mẫu, nó không cần biết về loại cơ sở cho chúng.

Ví dụ: lớp mẫu cho ma trận sẽ sử dụng toán tử +, -, * trên loại mục tiêu của nó. Trong đó có thể được sử dụng cho bất kỳ loại nào hỗ trợ các toán tử đó. Nếu nó bị giới hạn tùy ý với double s và int s, thì bạn không thể sử dụng mẫu với complex<double> hoặc chạy thử nghiệm với loại hỗ trợ số học khoảng, mặc dù các loại đó cung cấp cho nhà khai thác đó và thư viện ma trận sẽ hợp lệ Sử dụng chúng.

Khả năng hoạt động trên các loại tùy ý có cùng hình dạng là sức mạnh của mẫu và làm cho chúng hữu ích hơn. Tùy thuộc vào mã máy khách để quyết định xem có hợp lệ để sử dụng mẫu đó với loại đó (miễn là nó biên dịch) và khách hàng luôn đúng. Không có khả năng làm việc trên các loại tùy ý có cùng hình dạng và yêu cầu chỉ định các hạn chế đối với các phương thức gọi khác với các phương thức của java.lang.Object là điểm yếu của generics.

2

Đây là một extension thật đáng buồn đã bị xóa khỏi tiêu chuẩn dự thảo của C++ 0x vì nó "chưa sẵn sàng".Tuy nhiên, có thể mô phỏng điều này bằng cách sử dụng các xác nhận tĩnh (đó là một phần của C++ 0x và Boost như mọi người đã đề cập ở đây).

1

này đã làm việc cho tôi:

#include <iostream> 

class MyBase {}; 
class A : public MyBase {};  
class B {}; 

template <class T> 
typename std::enable_if<!std::is_base_of<MyBase, T>::value>::type 
Foo(T &v) { 
    std::cout << "Foo 1" << std::endl; 
} 

template <class T> 
typename std::enable_if<std::is_base_of<MyBase, T>::value>::type 
Foo(T &v) { 
    std::cout << "Foo 2" << std::endl; 
} 

int main() { 
    A a; 
    B b; 
    Foo(a); 
    Foo(b); 
    return 0; 
} 
+0

câu hỏi đặt trước 'is_base_of' (và' enable_if' cho vấn đề đó), hôm nay đây phải là giải pháp mặc định – Ap31

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