派生型を知らずに、派生ポインタを含むstd :: anyをベースポインタにキャストする方法はありますか?


8

std::any特定の基本クラスの派生クラスへのポインタを含む場合と含まない場合があるオブジェクトがあるとしますB。私ができることはありますか?

  1. 返しB *、あればstd::anyオブジェクトはコンバーチブル何かを保持するB *、または
  2. そうでない場合、例外をスローしますか?

それはのように思えるdynamic_castし、std::any_castそれぞれが、この機能の半分を提供しますが、私は2つを一緒に入れてのいずれかの方法で表示されません。

に変換可能なすべての型を明示的に列挙することを含むさまざまな方法でこれを機能させることができることは知っていますがB *、それはすべてのDRY違反の母です。


使用例:

std::vector<std::any> setupTools(const std::string & confFile)
{
  std::vector<std::any> myTools;

  auto conf = parse(confFile);

  for(std::string & wrenchInfo : conf["Wrenches"])
  {
    Wrench::setup(myTools, wrenchInfo);
  }    

  for(std::string & hammerInfo : conf["Hammers"])
  {
    Hammer::setup(myTools, hammerInfo);
  }

   // 25 more kinds of tools
}

Factory1::init(const std::vector<std::any> & tools)
{
  m_wrench = any_get<Wrench *>(tools);
  m_hammer = any_get<Hammer *>(tools);
  m_saw = any_get<Saw *>(tools);
}

Factory2::init(const std::vector<std::any> & tools)
{
  m_wrench = any_get<TorqueWrench *>(tools);
}

Factory3::init(const std::vector<std::any> & tools)
{
  m_saw = any_get<CordlessReciprocatingSaw *>(tools);
}

-私はちょうどので、私はのこぎりつかむことができる存在でのこぎりのすべての単一の種類をリスト定型コードの束含めたくない任意の Saw -で使用するがFactory1


1
なぜstd::anyこれを使用する必要があるのか、そして全体的に何を解決しようとしているのかについて説明できますか?これは非常に厄介な問題のように聞こえ、おそらくそれを回避するより良い方法があるでしょう
igel

3
明白なことを述べるリスクがあるので、B*sをstd::anyオブジェクトに入れるだけで、派生クラスのポインタは入れないことに同意すると、問題は非常に簡単に解決します。
ブライアン

2
それがあなたのユースケースに適合しない場合、あなたのユースケースを説明できますか?
Alan Birtles

1
すべての場合はmyToolsツールがある理由だけではなく、持っているTool基本クラスを作ると?myToolsstd::vector<std::unique_ptr<Tool>>
Alan Birtles

1
@DanielMcLaury:「のこぎりとハンマーの間に重複する機能はありません」では、なぜ同じ配列にあるのですか?それらを同じ場所に固定したいように見えるので、それらの間には明らかにいくつかの論理的な共通点があります。つまり、なぜmyTools存在するのか理解できません。完全に異なるオブジェクトであると主張するものをその中に入れ、次にそれらを反復して、そこに何を入れたかを思い出そうとするのはなぜですか?
Nicol Bolas

回答:


2

これは達成不可能です。std::any内部に置かれた型を正確に使用してオブジェクトを取り出すことのみが可能です。したがって、何かを取得するには、タイプを知っている必要があります。

と思われるstd::anyあなたのユースケースに適合していません。


0

列挙型のToolType属性を持つ基本クラス「Tool」を追加すると役立ちます。次に、ToolTypeを使用してキャストを決定できます。


1
これはうまくいく、私はそれが終わったのを見てきました。しかし、それは巨大なコードのにおいなので、お勧めしません。
Mark Ransom

はい、同意します。アーキテクチャを再考する方が良いでしょう。
ペドロフェレイラ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.