2016-10-13 10 views
5

boost :: cppライブラリの書籍を使って例をテストしているときに、boost :: any変数に格納されている型を変更すると、例外ではなく不正アクセスが発生する可能性があることに気づいた。boost ::不正なアクセスにつながる任意の型の変更

良い:

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

悪い:ので

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 

私の質問です:これはバグであるそれはそうか、それは私のテンプレートの使用に関連するいくつかの基本的な事実であるとして、気づいていないのですか?

+3

「博士は、それは私がこのように私の腕を動かしたときに痛いです。」 ... "そうですね、あなたの腕をそっと動かさないでください。" –

+1

'v = boost :: any a = 1; bool * p = boost :: any_cast (&a); //いいえ、悪いキャストの例外 '何?いいえ、それは起こりません。 – Yakk

+0

Ami Tavoryが間違ったコードセクションを見ていたことを指摘してくれてありがとうございます。彼の説明は健全なので、質問のコードを更新しました。 –

答えて

6

私は違ったthe documentationを理解する:

戻り値:ポインタを渡された場合は成功し、そうでない場合はnullが返された場合、それは価値のコンテンツと同様に資格のポインタを返します。 TがValueTypeの場合、保持されている値のコピーを返し、そうでない場合は、Tが(場合によってはconst修飾された)ValueTypeへの参照である場合、保持されている値への参照を返します。

例外:のいずれかを取るオーバーロードは、ポインタをスローしません。 いずれかの値または参照を取るオーバーロードは、bad_any_castが失敗した場合にスローされます。だから、

  1. 変換の成否は、格納されたタイプとターゲットのタイプによって異なります。

  2. しかし、障害の現れは、any_castへのポインタを渡すかどうかによって異なります。ポインタを渡すと、表現はnullptrになります。さもなければ、その現れは例外です。

例えば、このコードを考えてみましょう:

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

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

これは、あなたの質問に声明と矛盾するようだ - それは、ポインタがかかるので、それはスローされませんが、ポインタがnullptrです:

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

これはOKだとき、それはどのように見えるかです:

int *q = boost::any_cast<int>(&a); 
    // Prints false 
    std::cout << std::boolalpha << (q == nullptr) << std::endl; 

それはポインタを取ることはありませんので、これは、スロー:文字列の保存タイプに同じ

try { 
     boost::any_cast<bool>(a); 
    } 
    catch(...) { 
     std::cout << "caught" << std::endl; 
    } 

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; 
    } 
} 
関連する問題