2012-02-16 23 views
7

Tôi bắt đầu xin lỗi nếu tôi đủ ngu ngốc để không tìm thấy câu trả lời nếu nó quá rõ ràng.C++: Làm thế nào để ngăn chặn mẫu chuyên con trỏ?

Tôi đã thấy hàng tá trang nói về việc có chuyên môn mẫu cụ thể cho các thông số con trỏ.

Mặc dù tôi muốn có thể ngăn chặn một mẫu chuyên tham số con trỏ nhưng tôi không thể tìm ra cách thực hiện việc này.

template< class T > 
void function(T arg) 
{ 
    //... 
} 

int main() 
{ 
    int i = 42; 

    function(i); // Ok 
    function(&i); // Die bastart with a compiler error! 
} 

Có thể không?

Cảm ơn.

+1

Khi bạn có quyền truy cập vào C++ 11, bạn chỉ có thể sử dụng static_assert – PlasmaHH

+1

Không nên là 'template '? – Jacob

+0

@Jacob: đã được sửa. – MSalters

Trả lời

14

Bạn có thể khai báo chuyên môn (trong trường hợp này đó là kỹ thuật chỉ là một tình trạng quá tải) nhưng không định nghĩa nó :)

template<typename T > 
void function(T arg) 
{ 
//... 
} 

template<typename T > 
void function(T* arg); //no definition 

int main() 
{ 
    int i = 42; 
    function(i); // Ok 
    function(&i); //ERROR 
} 
+0

Đây có phải là lỗi liên kết hoặc lỗi biên dịch không? –

+4

@ daknøk: Đó là lỗi trình biên dịch vì đó là mẫu. Định nghĩa của mẫu phải nằm trong cùng một đơn vị dịch (tệp nguồn). Trình liên kết không biết gì về các mẫu. Trình biên dịch chịu trách nhiệm cho việc khởi tạo mẫu, và nó không thể làm điều đó mà không có định nghĩa –

+0

+1 Hah, tất nhiên, điều đó dễ dàng! Tại sao tôi luôn muốn làm điều đó một cách khó khăn? –

6

Tôi bản thân mình một tân binh mẫu Lập trình meta, nhưng tôi nghĩ

template<typename T> 
void function(typename std::enable_if<!std::is_pointer<T>::value,T>::type arg) 
{ 
    //... 
} 

nên hoạt động, vì chức năng này chỉ nên tồn tại đối với các tham số không phải con trỏ. Tất nhiên điều này đòi hỏi C++ 11 hoặc ít nhất là các cơ sở kiểu TR1 hoặc các đặc điểm kiểu tăng cường.

+0

+1 Tôi đã thử nghiệm một giải pháp thay thế (tôi sử dụng một chút): 'mẫu tên tệp enable_if :: giá trị> :: kiểu hàm (T arg)', nhưng bạn cũng nên làm việc. (Và cả hai kích hoạt * trình biên dịch * lỗi, chứ không phải là lỗi liên kết) –

7

Trong C++ 11, bạn có thể sử dụng static_assert theo một cách như thế này:

template<class T> 
void func(T arg) { 
    static_assert(!std::is_pointer<T>::value, 
       "The argument to func must not be a pointer."); 
    // Do something after the static_assert. 
    // Now you are sure that T isn't a pointer. 
} 

Một ví dụ có thể được tìm thấy here on Ideone.

Tôi khuyên bạn nên điều này vì nó sẽ cung cấp thêm thông báo lỗi hữu ích khi ai đó cố gắng gọi hàm của bạn bằng con trỏ (lỗi liên kết có thể rất khó hiểu trong trường hợp này). Ngoài ra, lỗi trình liên kết sẽ không hiển thị trước khi xảy ra liên kết.

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