Bir vektör öğesi olarak 0 tamsayısından işaretçiye örtük dönüşümlerden nasıl kaçınılır


11

JSON'da bir anahtar yolunun tüm düğüm adlarını toplamak istediğim bir durum var. "0" dizi indeksinin durumuna da izin verilsin, ancak alıntıları unutmak kolaydır, bu da dereference olduğunda çökmeye neden olur. Bu yüzden bunu reddetmek istiyorum. Misal:

#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;
}

Bunu buldum ve denedim Yapıcı olmayan işlevlerde örtük dönüşümleri nasıl önleyebilirim? aşağıdaki gibi:

#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;
}

Ama derleyici beni hala anlamadı.

Herhangi bir öneri?
Lütfen terminolojilerin ve varsayımların kötüye kullanılmasına dikkat edin, teşekkürler!


std::vector<const char*>Bunun yerine kullanmanız için bir neden var std::vector<std::string>>mı?
bolov

nullptrAyrıca yasaklamak ister misiniz ?
Jarod42

@bolov Başlangıçta bu düğüm adlarını girdi olarak C stili char * kullanan bir JSON analiz arayüzüne aktarmayı düşünüyorum, ancak bu burada sınırlı değil. Test ettik, std :: vector <std :: string >> kullanarak derleme sırasında hala 0 kabul, ancak çalıştırıldığında çöküyor, benim makine GCC raporları "basic_string :: _ M_construct null geçersiz".
rustyhu

@ Jarod42 Evet, C stili dizgi değişmezi ne istiyor.
rustyhu

Yanıtlar:


10

Böyle bir şey mi? Önerdiğiniz aşırı yük çözümüne çok benzer, ancak vektör türünün sarılmasını gerektirir. 0Silinmiş kurucu aşırı yüklenmesi seçildiği için bir değişmez değer sağlarsanız oluşturulamaz.

#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

Geriye dönüp bakıldığında, C ++ 'daki örtük dönüşümlerin çoğu talihsizdir, bu onlardan biri.

Dikkate alınması gereken bir seçenek -Wzero-as-null-pointer-constantgcc ve clang üzerindedir. Bu, standart programların davranışını değiştirdiğinden ve global olarak etkinleştirilirse bazı istenmeyen etkilere neden olabileceğinden emin olun.

örtük dönüştürmeyi 0'dan işaretçi türlerine nasıl devre dışı bırakabilirim?

Hangi Clang uyarısı GCC'den Wzero-null-pointer-sabiti ile eşdeğerdir?


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.