2015-02-10 25 views
18

Benim bir meslektaşım bugün temelde böyle gitti bizim kodunda çok ince hata, ortaya:Dize niçin `operator = (char)` işlevini destekliyor?

double d = 65; 
std::string s = "Hello world"; 

// .. somewhere later, accidentally assigning to s instead of a similarly 
// named numerical variable. 
s = d; 

// s is now 'A' 

bu hata buldum, std::basic_string<_Elem> bir atama operatörü olmasıdır oluşabilir nedenini

(seviye yeterince yüksek ise çok, bu daralması dönüşüm hakkında bir uyarı yayar)

_Myt& operator=(_Elem _Ch) 
{ // assign 1 * _Ch 
    return (assign(1, _Ch)); 
} 
Şimdi derleyici gerçekten şikayet etmiyor. Görünüşe göre bu hatayı yeterince erken yakaladık ki çok fazla hasar vermedi, ama neden buna izin verildiğini merak ediyordum. std::string bir char alan bir (n örtülü) yapıcısı olmadığı için de olsa ben

std::string s = 65; 

yazamazsınız. Eğer

std::string s = string('A'); 

yazmaya ve bu tek _Elem (char) için atama yasaklamak olurdu o bunu zorlar açık bir dönüşüm yapmak için daha güvenli olmaz.

bu atama operatörü sağlandı bir nedeni var mı? Aynı meslektaşı doğru fark olarak,

double d; 
char c = d; 

int* p = d; 

ise bırakılır olmayan (herhangi bir ibre boyutu için) olan - muhtemelen işaretçi dizi kapalı dönüştürme tehlikeli kabul edilir, çünkü. Aslında, gördüğüm kadarıyla, veri tipi yönetiminde oldukça katı ve yardımcı olmaya çalışan C++ 11'e dönüşmüş gibi görünüyor.

+10

Bu yüzden uyarıları daima yüksek tutuyorsunuz! "bir çift ve bir char dört bayt sığar" bu ne anlama geldiğinden emin değil. Onlar farklı boyutlarda. –

+4

@NeilKirk Varsayılan olarak, kurulu öntanımlı uyarı düzeyi neden yüksek değil? Kimse, derleyicilerinin, müşterilerinin kodlarını, tüm kötü uygulamaları hakkında bir uyarı denizine gömen ilk kişi olmasını istemiyor mu? –

+1

"bunu C++ 11'e dönüştürmüş gibi görünüyor" - çünkü onu kaldırmak eskiyen kodun kırılmasına neden olabilir, bu yüzden hafif bir şey yapamazsınız. –

cevap

16

Biri 30 yıl önce bunun iyi bir fikir olduğunu düşündüm std::string aktarım yapılan kütüphane kim yazdı.

standardizasyon önce, kaldırılmadı.

O zamandan beri, çıkarmadan bir maliyettir eski kodu, kırma risk olur.

deprecated nitelik

sadece kısa bir süre gidecek bir fonksiyonun kullanıcı anlatmak için standart bir yol sağlar C++, son zamanlarda eklendi. Kimse onu kullanımdan kaldırmayı başaramadı, bu da kaldırılmadan önce duyulması gereken mantıklı bir adımdır (sadece onu kaldırmak kaba olurdu). Böyle bir teklif yapmanızı tavsiye ederim.

+2

[[kullanımdan kaldırılmış]] özniteliğini bu üye işlevine eklemenizi ve C++ 17 ile kaldırmanızı öneririm. Sonuçta, kolayca bir destekli başlangıç ​​listesine, örneğin 's = {'5'};' – Columbo

+2

@ Columbo C++ 17 ile kaldırılması aşırı derecede agresif görünüyor: kaldırılmadan önce en az bir standart düzeltme için kullanımdan kaldırılmalıdır. C++ 17 için [[kullanımdan kaldırılmadı]], sonra da C++ 2x veya C++ 2y'de kaldırmayı önereceğim. – Yakk

+2

Whoops! Benim hatam. "C++ 17'den sonra standart olarak" demek istedim. Açıkçası, yalnızca C++ 17'de özniteliği tanıtabiliriz. :) – Columbo