2012-11-04 30 views
5

Tôi muốn tạo một hàm chung cho std :: stoi, std :: stof, std :: stod vv .. như:Chức năng chung cho một họ các hàm liên quan (ví dụ: std :: stoi, std :: stof, std :: stod, v.v.)

// std::string -> int 
std::string str = "1000000"; 
int i = to_numeric<int>(str); 

// std::string -> long 
std::string str = "100000000000"; 
long i = to_numeric<long>(str); 

// std::string -> float 
std::string str = "10000.1"; 
float i = to_numeric<float>(str); 

Nhưng tôi không biết làm thế nào để làm cho chuyên môn hóa từng phần:

template<class T> 
int to_numeric(const std::string &str, size_t *pos = 0, int base = 10) { 
    return std::stol(str, pos, base); 
}; 

template<> 
long to_numeric<long>(const std::string &str, size_t *pos, base) { 
    return std::stol(str, pos, base); 
}; 

template<> 
float to_numeric<float>(const std::string &str, size_t *pos) { 
    return std::stof(str, pos); 
}; 
// ..... 

lỗi:

to_numeric.cpp:76:79: error: default argument specified in explicit specialization [-fpermissive] 
to_numeric.cpp:76:12: error: template-id 'to_numeric<float>' for 'float to_numeric(const string&, size_t*)' does not match any template declaration 
make: *** [build] Error 1 
+3

Tôi chỉ sử dụng 'boost :: lexical_cast'. – chris

+0

Tôi không có Boost, nhưng tôi đã C++ 11 với cùng chức năng – Robbin

+0

Vì bạn cần phải xác định loại mục tiêu, tại sao phải bận tâm? Đối với các hàm chung, có người dùng chuyển một cuộc gọi lại thực hiện chuyển đổi, có thể là 'std :: stoi' và family. Ngoài ra, vì điều này không rõ ràng về một tính năng C++ 11 (bạn chỉ cần sử dụng một trong việc thực hiện, nhưng bạn có thể gọi bất cứ điều gì khác là tốt), tôi đã chỉnh sửa các thẻ. – Xeo

Trả lời

3

Bạn chỉ định một mẫu chính có ba đối số (str, posbase) nhưng bạn cố gắng chuyên mẫu với các mẫu chức năng chỉ lấy một đối số. Rõ ràng, điều này không hoạt động: Các chuyên môn cần phải khớp với mẫu chính.

Chuyên môn từng phần của mẫu chức năng chưa được hỗ trợ. Nếu bạn cần một mẫu chức năng chuyên ngành một phần, bạn cần phải thực hiện chuyên môn từng phần một cách gián tiếp: Bạn sẽ ủy quyền cho một mẫu lớp và một phần chuyên biệt đó. Mẫu lớp có thể chỉ có một hàm static. Tất nhiên, trong ví dụ của bạn, bạn không sử dụng chuyên môn hóa một phần nhưng chuyên môn hóa đầy đủ.

+0

Bạn có thể vui lòng cung cấp một ví dụ đơn giản không? – Robbin

+0

@Robbin: Một ví dụ đơn giản về những gì ...? Sửa mã của bạn nên thẳng về phía trước (thêm các tham số còn thiếu và, như Joachim Pileborg đã chỉ ra, cung cấp cho mẫu chính kiểu trả về 'T') và sử dụng chuyên môn hóa một phần tôi phải thừa nhận rằng tôi sẽ không biết bạn muốn ở đâu muốn sử dụng chuyên môn hóa một phần trong ngữ cảnh này! –

+0

Xin lỗi vì sự hiểu lầm của tôi, tôi nhận ra sai lầm của mình) – Robbin

2

Để bắt đầu, bạn phải làm cho chức năng mẫu không chuyên biệt hoàn toàn được tô điểm. Điều đó có nghĩa là bạn phải thực hiện kiểu trả về T. Tôi cũng khuyên rằng chức năng không chuyên biệt này không làm gì hơn là trả lại ví dụ: T() (vì nó không phải là chuyên ngành và không biết chức năng để gọi).

Để tiếp tục, chuyên môn to_numeric<float> cần có các đối số cùng làm chức năng không chuyên môn, vì vậy bạn cần thêm đối số giả base.

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