2016-06-05 22 views
14

tôi có dưới đây function (Chỉ cần để tái tạo vấn đề):Template luận khấu trừ cho 'char *'

template <typename KeyT> 
void func(const KeyT cptr) { 
    std::cout << typeid(KeyT).name() << std::endl; 
} 

Tôi muốn gọi này với một chuỗi chữ, như dưới đây:

func<char*>("literal"); 

Nhưng, tôi cuối cùng nhận được dưới đây cảnh báo:

 
warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wc++11-compat-deprecated-writable-strings] 

tôi có một nhu cầu cụ thể để sử dụng char* as type chính của tôi và tôi đã cũ pecting TAD để xem xét param type là toàn bộ như tôi không dùng nó bằng cách tham chiếu.

Cảnh báo đi kèm với cả hai trình biên dịch clangg++.

Làm cách nào để khấu trừ param type ở đây?

Xin cảm ơn trước.

+6

'cptr' kết thúc bằng một con trỏ tới ký tự (' char * const'), không phải là con trỏ tới const char. – melpomene

+0

@melpomene Điều đó kết thúc như thế nào? – Arunmu

+0

Tuyên bố của bạn nói 'cptr' phải là' const', và bạn khởi tạo 'KeyT' bằng' char * '. Vì vậy, 'cptr' là một const KeyT (với KeyT = pointer-to-char). – melpomene

Trả lời

12

tôi đã mong TAD để xem xét các loại param như const char * ...
Làm thế nào là loại param được suy luận ở đây?

template <typename KeyT> 
void func(const KeyT cptr) 

Lưu ý rằng const là vòng loại trên KeyT chính nó, nó có nghĩa là nếu KeyT là một con trỏ, sau đó cptr sẽ là một con trỏ const, không phải là một con trỏ đến const.

"literal" là trích dẫn chữ với loại const char[8], có thể phân hủy thành const char*. Sau đó, KeyT có thể được suy ra là const char*, sau đó loại cptr sẽ là const char* const.

Bạn đang chỉ định loại đối số mẫu là char*, sau đó đặt cptr a char* const. Nhưng từ C++ 11, việc chuyển đổi một chuỗi ký tự thành char* hoàn toàn không được phép vì các chữ cái là const.

Tại sao bạn cần loại thông số mẫu là char*? Để sửa đổi nó bên trong chức năng? Lưu ý rằng sửa đổi một chuỗi chữ sẽ dẫn đến UB. Bạn có thể vượt qua một mảng char với nó, như:

char my_chararray[] = "literal"; 
func<char*>(my_chararray); // or just func(my_chararray); 
+0

'Tại sao bạn cần kiểu tham số mẫu là char *? Để sửa đổi nó bên trong hàm? Không, đây chỉ là một ví dụ mà tôi đã thể hiện. Tôi đang thực sự sử dụng 'char *' như là một loại khóa cho một số container tự tạo mà sẽ được sao chép các chữ được cung cấp vào cấu trúc dữ liệu container. Tôi muốn thử nó mà không sử dụng các đặc tính 'remove_const' /' decay'. – Arunmu

+0

@Arunmu Nếu bạn không sửa đổi nó, sử dụng 'const char *' sẽ ổn (chỉ định đối số mẫu là 'const char *' hoặc không chỉ định). Nếu không, bạn phải làm một cái gì đó giống như câu trả lời của tôi cho thấy. – songyuanyao

+0

vâng, đó là những gì nó trông giống như. Tôi cần phải suy nghĩ lại về giao diện của mình. – Arunmu

8

Không có trích ở đây: bạn đã tuyên bố một cách rõ ràng rằng các tham số mẫu là char*.

Điều bạn đang thiếu là thay thế thông số không phải là tìm kiếm và thay thế văn bản: nó thực sự tuân theo các quy tắc lôgic cho hệ thống kiểu. const KeyT cptr khai báo một cá thể const thuộc loại KeyT — khi KeyTchar*, khai báo tham số trở thành char *const cptr.

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