最終更新日時(UTC):
が更新

履歴 編集

function template
<any>

std::any_cast(C++17)

namespace std {
  template <class T>
  T any_cast(const any& operand);                 // (1)

  template <class T>
  T any_cast(any& operand);                       // (2)

  template <class T>
  T any_cast(any&& operand);                      // (3)

  template <class T>
  const T* any_cast(const any* operand) noexcept; // (4)

  template <class T>
  T* any_cast(any* operand) noexcept;             // (5)
}

概要

std::anyオブジェクトが保持している値を取り出す。この関数に指定する型は、anyオブジェクトが保持している値が変換可能な型ではなく、保持している値の型と (const/参照の修飾を除いて) 同じでなければならない。

  • (1), (2), (3) : std::anyオブジェクトが保持している型を指定して、その値のコピーまたは参照を取得する。コピーで取り出す場合はany_cast<int>(x)、参照で取り出す場合はany_cast<int&>(x)のように指定する。型の指定を間違った場合は例外が送出される
  • (4), (5) : std::anyオブジェクトが保持している型を指定して、その値を指すポインタを取得する。型の指定を間違った場合はヌルポインタが返る

要件

using U = remove_cv_t<remove_reference_t<ValueType>>;であるとして、

  • (1) : is_constructible_v<ValueType, const U&> == trueであること。そうでない場合、プログラムは不適格となる
  • (2) : is_constructible_v<ValueType, U&> == trueであること。そうでない場合、プログラムは不適格となる
  • (3) : is_constructible_v<ValueType, U> == trueであること。そうでない場合、プログラムは不適格となる

効果

using U = remove_cv_t<remove_reference_t<ValueType>>;であるとして、

  • (1), (2) : operandオブジェクトが保持しているU型オブジェクトを返す
  • (3) : operandオブジェクトが保持しているU型オブジェクトをムーブして返す
  • (4), (5) : operand != nullptrかつoperand->type() == typeid(T)である場合、operandが保持しているT型オブジェクトへのポインタを返す

例外

#include <cassert>
#include <any>
#include <string>

int main()
{
  // (1)
  {
    const std::any x = 3;

    // コピーを取り出す
    int r1 = std::any_cast<int>(x);
    assert(r1 == 3);

    // 参照を取り出す
    const int& r2 = std::any_cast<const int&>(x);
    assert(r2 == 3);

    // xオブジェクトが保持している値はint型で、long long型に変換可能だが、
    // any_cast関数には直接の型intを指定しなければならない
    try {
      std::any_cast<long long>(x);
      assert(false);
    }
    catch (std::bad_any_cast& e) {
      // 型の指定を間違うと、bad_any_cast例外が送出される
      assert(true);
    }
  }

  // (2)
  {
    std::any x = std::string{"Hello"};

    // コピーを取り出す
    std::string r1 = std::any_cast<std::string>(x);
    assert(r1 == "Hello");

    // 参照を取り出す
    std::string& r2 = std::any_cast<std::string&>(x);
    assert(r2 == "Hello");
  }

  // (3)
  {
    std::any x = std::string{"Hello"};

    // anyクラスの一時オブジェクトから値をムーブして取り出す
    std::string r = std::any_cast<std::string>(std::move(x));
    assert(r == "Hello");
  }

  // (4)
  {
    const std::any x = 3;

    // 保持している値へのポインタを取り出す
    const int* p1 = std::any_cast<int>(&x);
    assert(*p1 == 3);

    // 型の指定を間違うとヌルポインタが返る
    const long long* p2 = std::any_cast<long long>(&x);
    assert(p2 == nullptr);
  }

  // (5)
  {
    std::any x = 3;

    // 保持している値へのポインタを取り出す
    int* p1 = std::any_cast<int>(&x);
    assert(*p1 == 3);

    // 型の指定を間違うとヌルポインタが返る
    long long* p2 = std::any_cast<long long>(&x);
    assert(p2 == nullptr);
  }
}

出力

バージョン

言語

  • C++17

処理系