Cách tránh chuyển đổi ngầm định từ int (0) sang con trỏ trong một vectơ


9

Có một tình huống mà tôi muốn thu thập tất cả các tên nút của một đường dẫn đến một khóa trong JSON. Xem xét điều kiện của chỉ số mảng "0", "1" cũng được cho phép, nhưng rất dễ quên các trích dẫn, điều này sẽ dẫn đến một sự cố khi thực hiện quy định. Vì vậy, tôi muốn từ chối điều này. Thí dụ:

#include <vector>
#include <iostream>

int func(const std::vector<const char*>& pin) {
    return pin.size();
}

int main() {
    // {"aname", "3", "path", "0"} wanted but this still compile
    std::cout << func({"aname", "3", "path", 0}) << std::endl;
}

Tôi đã tìm và thử điều này Làm cách nào để tránh chuyển đổi ngầm định trên các hàm không xây dựng? như sau:

#include <vector>
#include <iostream>

int func(const std::vector<const char*>& pin) {
    return pin.size();
}

template<typename T>
int func(T pin) = delete;

int main() {
    std::cout << func({"aname", "3", "path", 0}) << std::endl;
}

Nhưng trình biên dịch vẫn không hiểu tôi.

Bất cứ đề nghị nào?
Xin vui lòng chỉ ra bất kỳ lạm dụng các thuật ngữ và giả định, cảm ơn bạn!


Có một lý do tại sao bạn sử dụng std::vector<const char*>thay vì std::vector<std::string>>?
bolov

Bạn có muốn cấm nullptrcũng không?
Jarod42

@bolov Lúc đầu, tôi cân nhắc chuyển các tên nút này cho giao diện phân tích JSON, sử dụng char * kiểu C làm đầu vào, nhưng điều này không giới hạn ở đây. Tôi đã thử nghiệm, sử dụng std :: vector <std :: string >> vẫn chấp nhận 0 khi biên dịch, nhưng gặp sự cố khi chạy, trên máy của tôi, GCC báo cáo "basic_opes :: _ M_construct null không hợp lệ".
rustyhu

@ Jarod42 Có, những gì muốn là chuỗi ký tự chữ C.
rustyhu

Câu trả lời:


9

Một cái gì đó như thế này? Nó rất giống với giải pháp quá tải mà bạn đề xuất, nhưng yêu cầu bọc kiểu vectơ. Không thể xây dựng nếu bạn cung cấp bằng chữ 0vì quá tải hàm tạo đã xóa được chọn.

#include <memory>
#include <new>
#include <vector>
#include <iostream>
using std::vector;

template<typename T>
struct no_zero {
        no_zero(T val) : val(val) {}
        no_zero(int val) = delete;
        operator T() { return val; }
        T val;
};

int func(const vector<no_zero<const char*> >& pin) {
    return pin.size();
}

int main() {
    // {"aname", "3", "path", "0"} wanted but this still compile
    std::cout << func({"aname", "3", "path", 0}) << std::endl;
}

4

Nhìn chung, nhiều chuyển đổi ngầm trong C ++ là không may, đây là một trong số chúng.

Một lựa chọn để xem xét là -Wzero-as-null-pointer-constanttrên gcc và clang. Hãy cẩn thận vì điều này thay đổi hành vi của các chương trình tiêu chuẩn và nếu được bật trên toàn cầu có thể có một số tác dụng ngoài ý muốn.

g ++ - làm cách nào để tắt chuyển đổi ngầm định từ 0 sang loại con trỏ?

Cảnh báo Clang nào tương đương với hằng số Wzero-as-null-con trỏ từ GCC?


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.