スポンサーリンク

| キーワード:

std::variant

C++でバリアント型を使う。C++17以降。

基本的な使い方

#include <cstdio>
#include <string>
#include <variant>

enum VARIANT_TYPES {
  V_INT = 0,
  V_STR = 1,
  V_DBL = 2
};

int main()
{

  std::variant<int, std::string, double> val;

  val = 2;
  //val = 5.5;
  //val = "abc";

  if (val.index() == V_INT) {
    int& x = std::get<V_INT>(val);
    printf("--- %d\n", x);
  }

else if(val.index()==V_STR){ std::string& s = std::get<V_STR>(val); printf("--- %s\n", s.c_str()); }
else if (val.index() == V_DBL) { double& d = std::get<V_DBL>(val); printf("--- %lf\n", d); } int k = getchar(); }

std::visit

std::variant型を引数で取る関数を作ってもいいが、std::visit関数でoperator()を定義したクラスのインスタンスを渡して呼び出す方が美しいらしい。

#include <cstdio>
#include <string>

#include <variant>


struct Print {

  // int が代入されたときに呼び出される
  void operator()(const int& data) {
    printf("--- %d\n", data);
  }

  // std::string が代入されたときに呼び出される
  void operator()(const std::string& data) {
    printf("--- %s\n", data.c_str());
  }

  // double が代入されたときに呼び出される
  void operator()(const double& data) {
    printf("--- %lf\n", data);
  }

};
int main()
{

  std::variant<int, std::string, double> val;

  val = 2;
  std::visit(Print(), val);

  val = 5.5;
  std::visit(Print(), val);

  val = "abc";
  std::visit(Print(), val);

  int k = getchar();
}

std::visitは第一引数に関数、第二引数以降はstd::variant型でなければならない(らしい)。

std::visit( 関数() , variant1 , variant2 , variant3 , … )

なので、std::visitの引数で渡す場合、std::variantで渡さなければいけない。

#include <cstdio>
#include <string>

#include <variant>


struct Print {

  // int が代入されたときに呼び出される
  void operator()(const int& data) {
    printf("--- %d\n", data);
  }

  // std::string が代入されたときに呼び出される
  void operator()(const std::string& data) {
    printf("--- %s\n", data.c_str());
  }

  // double が代入されたときに呼び出される
  void operator()(const double& data) {
    printf("--- %lf\n", data);
  }

};

struct Add {

  // int が代入されたときに呼び出される
  void operator()(int& data, const int val) {
    data += val;
  }

  // std::string が代入されたときに呼び出される
  void operator()(std::string& data, const int val) {
    data += std::to_string(val);
  }

  // double が代入されたときに呼び出される
  void operator()(double& data, const int val) {
    data += val;
  }

};
int main()
{

  std::variant<int, std::string, double> val;


  val = 2;
  std::visit( Add(), val,std::variant<int>(4) );
  std::visit(Print(),val);

  val = 5.5;
  std::visit( Add(), val, std::variant<int>(4));
  std::visit(Print(), val);

  val = "abc";
  std::visit( Add(), val, std::variant<int>(4));
  std::visit(Print(), val);

  int k = getchar();
}

引数を渡すならコンストラクタに渡した方がスマートだと思う。

#include <cstdio>
#include <string>

#include <variant>


struct Print {

  std::string _sign;
public:
  Print(const std::string& sign):_sign(sign) {}

  // int が代入されたときに呼び出される
  void operator()(const int& data) {
    printf("%s %d\n",_sign.c_str(), data);
  }

  // std::string が代入されたときに呼び出される
  void operator()(const std::string& data) {
    printf("%s %s\n", _sign.c_str(), data.c_str());
  }

  // double が代入されたときに呼び出される
  void operator()(const double& data) {
    printf("%s %lf\n", _sign.c_str(), data);
  }

};
int main()
{

  std::variant<int, std::string, double> val;


  val = 2;
  std::visit(Print(">>"),val);

  val = 5.5;
  std::visit(Print(">>"), val);

  val = "abc";
  std::visit(Print(">>"), val);

  int k = getchar();
}

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: