2016-10-13 19 views
5

Destek cpp kitaplıkları kitabındaki örnekleri sınarken, bir destek dosyasında saklanan türün değiştirildiğini fark ettim: herhangi bir değişken bir istisna yerine yasa dışı bir erişime yol açabilir:boost :: yasadışı erişime yol açan her tür değişiklik

iyi:

boost::any a = 1; 
bool *p = boost::any_cast<bool>(&a); // ok, bad cast exception 

kötü:

boost::any a = std::string { "Boost" }; 
a = 1; 
bool *p = boost::any_cast<bool>(&a); // no exception thrown 
std::cout << std::boolalpha << *p << '\n'; // illegal access 

sorum yanlı olup olmadığı görünüyor yoksa şablonlar kullanımı ile ilgili bazı temel gerçektir olarak bu bir hata olduğunu ben farkında değil miyim?

+3

... "Eh, kolunu bu şekilde hareket ettirme." –

+1

'v = boost :: any a = 1; bool * p = boost :: any_cast (&a); // tamam, kötü cast istisnası ne? Hayır, bu gerçekleşmez. – Yakk

+0

Teşekkür ederim, haklısın, Ami Tavory'nin de yanlış kod bölümüne baktığını belirtti. Ancak açıklaması açık olduğundan, söz konusu kodu güncelledim. –

cevap

6

ben farklı the documentation anlıyorum:

İade: bir işaretçi geçirilen Eğer başarılı, aksi boş döndürülür eğer, değerin içeriğine benzer nitelikli gösterici ile döner. T ValueType ise, T (muhtemelen const nitelikli) ValueType, bu tutulan değerine bir referans resmi belgeler ise, bu, aksi takdirde, elde tutulan değerinin bir kopyasını verir.

Atmalar: atmayın bir herhangi işaretçisi alarak Overloads; başarısız olursa bir herhangi değeri veya referans alarak aşırı yükler bad_any_cast atar. Yani

:

  1. dönüşüm başarılı veya başarısız saklanan tipi ve hedef türüne bağlıdır.

  2. olsa başarısızlık tezahürü, sen any_cast veya olmasın bir işaretçi geçmesi olmadığına bağlıdır. Bir işaretçiyi iletirseniz, tezahürü bir nullptr; aksi halde tezahür, bir istisnadır.

örneğin bu kodu düşünün:

#include <boost/any.hpp> 
#include <iostream> 

int main() { 
    boost::any a = 1; 

Bu sorunuzu ifadeyi çelişir görünen - bir işaretçi alır, çünkü o atmak yok, ama işaretçi nullptr geçerli:

bool *p = boost::any_cast<bool>(&a); 
    // Prints true 
    std::cout << std::boolalpha << (p == nullptr) << std::endl; 

Bu sorun yok zaman nasıl görünüyor geçerli:

int *q = boost::any_cast<int>(&a); 
    // Prints false 
    std::cout << std::boolalpha << (q == nullptr) << std::endl; 
o bir işaretçi almaz çünkü

Bu, atar:

bir dize depolanan türü için
try { 
     boost::any_cast<bool>(a); 
    } 
    catch(...) { 
     std::cout << "caught" << std::endl; 
    } 

aynı: "Ben bu şekilde kolumu hareket ettirdiğinizde Doktor, acıyor"

a = std::string { "Boost" }; 
    p = boost::any_cast<bool>(&a); 
    // Prints true 
    std::cout << std::boolalpha << (p == nullptr) << std::endl; 
    try { 
     boost::any_cast<bool>(a); 
    } 
    catch(...) { 
     std::cout << "caught again" << std::endl; 
    } 
}