最終更新日時: 2026年02月11日 14時29分19秒 (JST)
yoh が更新

履歴 編集

function
<ios>

# std::ios_base::pword

    void*& pword(int idx);

## 概要

`void*` 型の私用記憶域への参照を取得する。

## 効果

`idx` で指定した記憶域がまだ確保されていなかった場合、新たに `void*` 型の記憶域を確保し、ヌルポインタで初期化する。 もし、記憶域の確保に失敗し、かつ、`*this` が `basic_ios` の基底サブオブジェクトの場合、`basic_ios::setstate(badbit)` を呼び出す（これは `failure` 例外を送出するかもしれない）。

## 戻り値

`idx` で指定した記憶域への参照。もし記憶域が確保できなかった場合（かつ`failure` 例外が投げられなかった場合）には、ヌルポインタに初期化された有効な `void*` 型への参照。

## 備考

- 引数 `idx` には、`xalloc` で取得した値を渡すことが想定されている。 そうすることによって、各プログラムが他のプログラムと競合すること無く各ストリームオブジェクト内に `void*` 型の私用記憶域を確保することが可能となる。
- 本関数で取得した `void*` への参照は、本オブジェクトの他の操作によって無効になる可能性がある。
  しかし、その場合でも引数 `idx` で指定した記憶域の内容は依然として有効である。
- 本関数で取得した `void*` 型の記憶域の内容は、`basic_ios::copyfmt` でコピーされる。
  ただし、コピーされるのはあくまでもポインタ値であるため、必要に応じてコールバックで対処を行うこと。（下記の例も参照）

## 例

    #include <iostream>
    #include <string>
    #include <sstream>

    // 任意の接尾辞を付加出力可能な string 型
    struct MyString {
      std::string value;
    };

    // 接尾辞を指定するためのマニピュレータ
    struct setsuffix {
      explicit setsuffix(const std::string& suffix) : suffix(suffix) {}
      friend std::ostream& operator<<(std::ostream& os, const MyString& x);
      friend std::ostream& operator<<(std::ostream& os, const setsuffix& manip);
    private:
      std::string suffix;
      static const int index;
      static void callback(std::ios_base::event ev, std::ios_base& str, int index) {
        void*& psuffix = str.pword(index);
        switch (ev) {
        case std::ios_base::erase_event:
          // デストラクタ、および、copyfmt のコピー前に string を delete
          delete static_cast<std::string*>(psuffix);
          break;
        case std::ios_base::copyfmt_event:
          // copyfmt のコピー後に string を複製
          psuffix = new std::string(*static_cast<std::string*>(psuffix));
          break;
        case std::ios_base::imbue_event:
          break;
        }
      }
    };

    // 記憶域用の添え字を取得
    const int setsuffix::index = std::ios_base::xalloc();

    // MyString 用の出力演算子
    std::ostream& operator<<(std::ostream& os, const MyString& x)
    {
      std::string* psuffix = static_cast<std::string*>(os.pword(setsuffix::index));
      return os << (psuffix == 0 ? x.value : x.value + *psuffix);
    }

    // マニピュレータ用の出力演算子
    std::ostream& operator<<(std::ostream& os, const setsuffix& manip)
    {
      void*& psuffix = os.pword(setsuffix::index);
      if (!os.bad()) {
        if (psuffix == 0) {
          // 初回はコールバックを登録して、string を割り当てる
          os.register_callback(setsuffix::callback, setsuffix::index);
          psuffix = new std::string(manip.suffix);
        } else {
          *static_cast<std::string*>(psuffix) = manip.suffix;
        }
      }
      return os;
    }

    int main()
    {
      MyString x = {"今日も一日がんばる"};

      std::cout << x << std::endl;                          // 普通に出力
      std::cout << setsuffix("ドン") << x << std::endl;     // どんちゃん風に出力

      std::stringstream ss;
      ss << setsuffix("ぞい");                              // ss を涼風青葉風出力に設定
      std::cout.copyfmt(ss);                                // ss から std::cout にフォーマットをコピー
      ss << setsuffix("(´･_･`)");                           // ss を tanakh さん風に設定変更
      std::cout << x << std::endl;                          // 涼風青葉風に出力（ss に対する変更は無影響）
    }

### 出力

    今日も一日がんばる
    今日も一日がんばるドン
    今日も一日がんばるぞい

なお、上記の例はコールバックで例外の適切な処置を行っていないので注意。
（コールバックは例外を送出してはいけない。`register_callback` の要件を参照）

## 参照

- `xalloc`
- `iword`
- `basic_ios::copyfmt`
- `register_callback`
- `event_callback`
- `event`