G ++ vs MSVC'de C ++ Tırnaklarının Anlamı

Muhtemelen bu soruyu cevaplayacak bir Google araması var ama benim için hayatım boyunca milyonlarca ilgisiz cevap alamayan bir şey düşünemiyorum.

Yani,

In MSVC text inside quotes "like this" is taken, I think, as a std::string or, maybe, std::string&. In g++/gcc it always seems to be taken as const char*. True?

Oynamak istediğim bir kod parçacığı buldum ve içeriyor

if(NULL == key)
   throw exception("Empty key");

MSVC/VC ++ (2008 (ancak bunu g ++ (4.4.3) üzerinde denediğimde

no matching functions for calls to std::exception::exception(const char&) 

Bunu çalışmak için aldım:

if (NULL == key)
{
   std::string   estr   ("Empty key");
   throw exception("Empty key");
}

Ama bu sadece çirkin.

Bu bana farklı hatalar verdi:

std::string   estr   ("");
if (NULL == key)
{
   estr = "Empty key";
   throw exception("Empty key");
}

I have no clue what exception() expects as its input. I did find something that suggested std::string or maybe std::string& but I lost that page and the millions of unhelpful pages I've found since are, well, useless. Have all kinds of info on exception class, exception use,....

Short of my ugly fix, is there a simple way to tell g++ that "this is a std::string" not a const char& and still keep VC++ happy? (obviously I'm trying to do cross compilable code from single source.)

Ve bu konuda, nasıl id

   throw exception("Empty key");

dan farklı

   throw "Empty key";

Teşekkürler,

Wes

0
istisna atmak (yeni std :: string ("Boş anahtar"));
katma yazar Dirk Dastardly, kaynak
@MikeSeymour: Tamam, belki yanlış anladım. Derleyici ona istisnanın bir std :: string'i beklediğini söylemiyor mu? Ve eğer durum böyleyse, std :: string'in içinden geçen bir istisnayı nasıl atacaksınız ki, o zaman imha edilmeyecek çünkü kontrol asla istisnanın dışındaki herhangi bir noktaya geri dönmeyecek?
katma yazar Dirk Dastardly, kaynak
@DrewBurchett: istisnası 'ın varsayılan olmayan kurucuları yoktur, bu nedenle işe yaramaz, bellek sızıntısı oluştursa bile iyi bir fikirdi (ki değil).
katma yazar Mike Seymour, kaynak
@DrewBurchett: Hata, eşleşen bir kurucu olmadığını ve beklenenin ne olduğunu söylemediğini söylüyor. runtime_error gibi exception standart alt sınıfları, başlangıç ​​nesnesinin kendisi kadar sürdüğü, başlattıkları dizenin bir kopyasını saklar.
katma yazar Mike Seymour, kaynak

4 cevap

Bir dize değişmezi, her zaman bir null sonlandırıcı ile harfleri karakterleri içerecek kadar büyük bir boyuta sahip bir char dizisi türüne sahiptir. Yani "Boş anahtar" char [10] türüne sahiptir. Gerekirse, örtülü olarak char const * veya std :: string olarak değiştirilebilir.

The error is because exception is intended as a base class for exception types, not something you instantiate directly. You should throw one of the types defined in such as std::runtime_error (which can be constructed using a string), or define your own type that inherits std::exception and overrides what().

Microsoft'un std :: exception için standart olmayan bir kurucu eklediğini tahmin ediyorum. Dili garip yollarla genişletmeyi severler.

3
katma
Mükemmel cevap! Çok teşekkürler.
katma yazar Wes Miller, kaynak
@MSalters: Tabii ki yasal ve eminim ki birileri istedikleri takdirde onu kamuya açıklamak için makul bir gerekçeyle ortaya çıkabilir. Bu, taşınabilirlik açısından (bu sorunun kanıtladığı gibi) kötü bir fikirdir.
katma yazar Mike Seymour, kaynak
@Gorpik: OP tarafından kullanılan eski versiyona benziyor (yayınlanan kodun gerçekten derlendiğini varsayarak ve istisnası diye başka bir tür yoktu std :: exception gizleniyor >); daha yeni versiyonlar, en az 4.4.5'ten beri.
katma yazar Mike Seymour, kaynak
Özellikle standart kitaplıktaki diğer istisnalar için bir taban türü olarak kullanılması amaçlandığından, standart olmayan bir kurucu eklemesi Microsoft için çok uygundur. Standart Kitaplık uygulamasının parçası olduklarından, bu diğer istisnalar temel sınıflarının uygulamaya özel yöntemlerini kullanabilir. uygulamaya özgü temel sınıfları kullanmak bile yaygındır.
katma yazar MSalters, kaynak
G ++ gibi görünen de std :: exception için standart dışı bir kurucuya sahiptir. Aksi takdirde, sorudaki ikinci örnek derlenmeyecekti.
katma yazar Gorpik, kaynak
@MikeSeymour: OP'nin sorusu üzerine yaptığım yorumu temel aldım çünkü ona güvenmemem için hiçbir nedenim yoktu. Ya ikinci örneğiyle yanlış ya da g ++ sıra dışı bir şey yaptı, yani küçük bir sürümdeki bir özelliği kaldırarak mevcut kodu bozabilir.
katma yazar Gorpik, kaynak

std :: string türüne göre istisnalar atmaktan kaçının çünkü bunlar bir istisna atarlar. Ve eğer bu olursa Tanımsız Davranış ile sonuçlanırsınız.

Throw standard exceptions defined in or have your own exception class derive from std::exception class and throw it.And override the what() method to add appropriate description of the exception.

Ayrıca, her zaman at değerine göre ve catch referans alınarak.

2
katma

std :: exception temel sınıftır.

Bunun yerine bir std :: runtime_error atmayı deneyin.

2
katma

"like this" is always regarded as an array of const char, according to the standard. This is not the problem here. What really happens is that std::exception only has the default constructor, once again according to the standard. It is usual to include an additional constructors taking a text string, but this constructor works differently in VC++ and g++, as your example shows.

Burada g ++ belgelerine sahip değilim, ancak örneklerden, standart dışı kurucuyu şöyle tanımlar:

explicit exception(const std::string&);

VC ++, standart olmayan yapıcıyı şöyle tanımlar:

açık istisna (const char *);

0
katma
Dize değişmezleri, işaretçiler değil, dizilerdir.
katma yazar Mike Seymour, kaynak
@MikeSeymour: Haklısınız, düzeltildiniz.
katma yazar Gorpik, kaynak