2015-06-13 18 views
5
transform(mystr.begin(), mystr.end(), mystr.begin(), tolower); 

Tôi đang sử dụng hàm chuyển đổi để tạo chuỗi tất cả các chữ thường, nhưng ngay cả sau khi viết "using namespace std;" ở trên cùng của chương trình của tôi, tôi nhận được một loạt các lỗi (khi viết như trên). Khi tôi bao gồm toán tử :: trước tham số của hàm không thích (như dưới đây) thì không. Tại sao điều này? Tôi nghĩ chức năng của người chịu đựng nằm trong không gian tên cũ và nó sẽ hoạt động như tôi đã nói ở trên.:: toán tử cần thiết để sử dụng với tolower()?

transform(mystr.begin(), mystr.end(), mystr.begin(), ::tolower); 

Tôi có những điều sau đây bao gồm:

#include <iostream> 
#include <fstream 
#include <sstream> 
#include <algorithm> 
#include <vector> 

Trong thông báo lỗi tôi thấy:

error: no matching function for call to 'transform(std::basic_string<char>::iterator, ... 

sau đó nó trở thành nơi 'ToLower' nằm trong danh sách tham số

, <unresolved overloaded function type>);' 
+5

Khi bạn có "toàn bộ các lỗi", thật hữu ích khi nói chính xác chúng là gì. –

Trả lời

3

:: là để nói nó nằm trong không gian tên chung. Nó chỉ làm cho nó rõ ràng

4

Tệp tiêu đề mà bạn đã bao gồm là gì? Đảm bảo rằng bạn bao gồm <cctype> và không phải <ctype.h> .. Trong <cctype> tất cả các chức năng đã được xác định trong không gian tên std.

6

Đó là để giải quyết mâu thuẫn giữa các quá tải của tolower giữa <cctype> 's int tolower(int c)<locale>' s mẫu <typename charT> charT tolower(charT c, locale const& loc)

::tolower sử dụng phạm vi toàn cầu

+1

... và giải pháp là đưa 'tolower' vào loại thích hợp, sẽ buộc độ phân giải:' static_cast (cho phép) ' – davmac

+1

(mặc dù Matt McNabb chỉ ra, điều đó không hoàn toàn chính xác). – davmac

6

Vâng, đây là một chút phức tạp. Thêm #include <cctype> có thể sẽ xuất hiện để khắc phục sự cố của bạn. Tuy nhiên vẫn còn một chút nữa.

Có hai phiên bản của tolower:

int std::tolower(int ch);       // #include <cctype> 

template<typename charT> 
charT std::tolower(charT ch, const std::locale& loc); // #include <locale> 

nhưng cũng có thể có phiên bản này:

int ::tolower(int ch); // #include <cctype> or #include <ctype.h> 

vì triển khai được phép tiêm tên từ std vào không gian tên toàn cầu. Ngoài ra, bạn không thể đếm trên cctype hoặc locale được bao gồm hay không, bởi vì mọi tiêu chuẩn bao gồm cũng có thể bao gồm bất kỳ tiêu chuẩn nào khác bao gồm.


Có vẻ như bạn đang có ý định sử dụng phiên bản từ <cctype>. Tuy nhiên, đó sẽ là một lỗi. Nếu bạn kiểm tra tài liệu cho phiên bản tolower đó, bạn sẽ thấy đối số phải là được chuyển đổi thành unsigned char trước khi được chuyển đến hàm.

IOW, chuyển số char có giá trị âm sang phiên bản cctype tolower gây ra hành vi không xác định. (Mặc dù các triển khai phổ biến hỗ trợ nó bởi vì đó là một sai lầm phổ biến).

Để sửa mã của bạn và vẫn sử dụng phiên bản cctype, bạn có thể viết:

#include <cctype> 

// ... 

transform(mystr.begin(), mystr.end(), mystr.begin(), 
    [](char ch) { return std::tolower((unsigned char)ch); }); 

mặc dù nó có vẻ hơi đơn giản để sử dụng:

for (char &ch : mystr) 
    ch = std::tolower((unsigned char)ch); 

Phiên bản <locale> sẽ trông như thế (nhớ rằng đó là mẫu chức năng):

#include <locale> 
#include <functional> 

// ... 

transform(mystr.begin(), mystr.end(), mystr.begin(), 
    std::bind(std::tolower<char>, std::placeholders::_1, std::locale())); 

hoặc

std::locale loc; 

for (char &ch : mystr) 
    ch = std::tolower(ch, loc); 
Các vấn đề liên quan