2016-06-13 7 views
0

これを理解するまでにはしばらく時間がかかりましたが、boost::anyの意味は混乱します。値型でboost ::ポインタとの混乱と値の比較

は、あなたがそうのようにそれを使用します。

int value = 100; 
boost::any something; 
something = value; 
//...later... 
int value = boost::any_cast<int>(&something); 

このコードは明確であり、理にかなっているが、店舗value内部コピーとして。つまり、大きなオブジェクトの場合は、boost::anyの中にコピーされます。コピーされます。また、void*をこれに置き換えた関数は、boost::anyオブジェクトに含まれる値を変更すると関数外の値が変更されることが予想されます(それはコピーされてから発生しません)。

私はそれにポインタを置くのであれば、物事は奇妙な取得:

​​

私はboost::any_cast戻りint**ので、この場合の戻り値を逆参照する必要があります!私もチェックしていないが、something.empty() == trueならこれがクラッシュするかもしれないと思う。これは全く単純ではありません。

私はboost::anyに値を格納したくないので、ポインタでのみ機能し、意味的にはvoid*の近くで動作するようにします。ポインタは、いくつかの型安全性が混在しています。本質的には、私が欲しいのはboost::any_pointerなのです。 boost::anyがポインタ以外のものを受け入れないようにする方法はありますか?それ以外の場合は、boost::anyの代わりに、私が探しているセマンティクスを得ることができますか?

+0

'boost :: any'はかなりeです作成するにはasyを、その後、セマンティクスを変更することができます。 –

+0

あなたの最初のスニペットはうまくいかず、逆参照が必要です(snippet2として)[Demo](http://coliru.stacked-crooked.com/a/df5bdb307f56b709) – Jarod42

+0

あなたはまだ 'boost :: any'をクラスにラップすることができますポインタのみを許可する。 – Jarod42

答えて

1

:私はあなたが(存在しないが)boost::any_pointerの行に何かを探しているので、あなたは、boost::anyにポインタを格納したいと仮定しています。

boost::any_castは、その内部に格納されている実際の値(ホルダ内のheldオブジェクト)へのポインタを返します。したがって、実際に後でコピーしない限り、コピーを保存します。

template<typename ValueType> 
    ValueType * any_cast(any * operand) BOOST_NOEXCEPT 
    { 
     return operand && operand->type() == boost::typeindex::type_id<ValueType>() 
      ? &static_cast<any::holder<BOOST_DEDUCED_TYPENAME remove_cv<ValueType>::type> *>(operand->content)->held 
      : 0; 
    } 

あなたは常にだけでポインタ型を許可するようにboost::anyの周りにラッパーを作成することができます

class MyAny { 
public: 
    template <typename T, 
     typename = typename std::enable_if<std::is_pointer<std::remove_cv<T>::type>::value>::type> 
    MyAny(T ptr): any_(ptr) {} 

template <typename ValueType> 
ValueType operator*() { 
    return *boost::any_cast<ValueType>(&any_); 
} 

private: 
    boost::any any_ 
}; 

上記は、大まかなコードである私がコンパイルされ、それをテストしていません。

std::enable_if type形質はC++ 11で利用可能であるが、ブーストにおいても見出すことができる。それはあなたのMyAnyをポインタ型に制限するものです。

1

あなたはany_cast間違っを使用している:

は、本質的に2つの(3)の味があります。

  • いずれかへの参照を取得し、任意のポインタをとるコンテンツ
  • に値または参照を返すと、コンテンツへのポインタを返す

例:

#include <boost/any.hpp> 
int main() 
{ 
    // Any holding a value 
    { 
     boost::any any_value(1); 
     // Throws bad_any_cast if the content is not 'int' (in this case): 
     int value = boost::any_cast<int>(any_value); 
     // Throws bad_any_cast if the content is not 'int' (in this case): 
     int& reference = boost::any_cast<int&>(any_value); 
     // Returns a null pointer if the content is not 'int' (in this case): 
     int* pointer = boost::any_cast<int>(&any_value); 
    } 

    // Any holding a pointer (which is nothing else but a value) 
    { 
     int integer = 0; 
     boost::any any_ptr(&integer); 
     // Throws bad_any_cast if the content is not 'int*' (in this case): 
     int * pointer = boost::any_cast<int*>(any_ptr); 
     // Throws bad_any_cast if the content is not 'int*' (in this case): 
     int*& pointer_reference = boost::any_cast<int*&>(any_ptr); 
     // Returns a null pointer if the content is not 'int*' (in this case): 
     int** pointer_pointer = boost::any_cast<int*>(&any_ptr); 
    } 
} 

参考:http://en.cppreference.com/w/cpp/experimental/anyhttp://en.cppreference.com/w/cpp/experimental/any/any_cast

+0

私はその構文が多くの人々を捨てるのを見ます。これはstd :: anyでも同じです。 –

+0

私は 'boost :: any'を使用している間に例外を避けようとしています。なぜなら、私はポインタのオーバーロードを使用しているからです。最初の例と2番目の例は、例外をスローするように見えます。私のテストでは少なくともそれはしました。 –

+0

ここに私が書いたサンプルがあります。私はそれをスローする必要はありません、型が間違っている場合、 'nullptr'が返されます:http://coliru.stacked-crooked.com/a/f6ffdf4387e335d6 –