メモの日々


2016年04月06日(水) [長年日記]

[c++] C++で型名と変数名を同じにしてみる

C++で型名と変数名を同じにしたいときにどうするか。

サンプルコード

次のように、クラスouter内にinnerと言う名前のクラスとメンバ変数を両方定義してみる。

#include <iostream>

struct outer {
  struct inner {
    void f() { std::cout << "hello" << std::endl; }
  };

  inner inner;
};

int main() {
  outer::inner a;
  a.f();
}

このコードはコンパイルエラーになる(g++ 4.8.5を使用)。main()内の「outer::inner」はクラス名ではなくメンバ変数名と解釈される。

次のように struct を補うとコンパイルできるようになる。

int main() {
  struct outer::inner a;
  a.f();
}

別名を使う

struct outer::inner は長いので、エイリアス宣言を使って別名を定義してみる。

int main() {
  using in = struct outer::inner;
  in a;
  a.f();
}

このコードは動作するが、g++は

warning: declaration 'struct outer::inner' does not declare anything [enabled by default]

という警告を出力する。とはいえ、structを省いて「using in = outer::inner;」と書くとコンパイルできない。警告が出るのはg++のバグである気がする。clangを使うと警告は出力されない。

試しにstructの代わりに「using in = typename outer::inner;」とtypenameを書いてみたら、g++ではコンパイルできた。しかし、clangではコンパイルエラーになる。この書き方は不正なのだろうと思われる。

g++でもclangでも警告なしにコンパイルするには、エイリアス宣言ではなくtypedefを使えばよい。

int main() {
  typedef struct outer::inner in;
  in a;
  a.f();
}

2016年04月12日(火) [長年日記]

[unix] エスケープシーケンスを綺麗に除去できない

scriptコマンドで作業の記録を取ろうとしたのだけれど、エスケープシーケンスまで記録されてしまうのが不便。

エスケープシーケンスを除去する丁度良いコマンドってなかなか無いみたい。検索すると colコマンドを使ったりsedで何とかしている例がヒットするけど、自分の環境だとどれもゴミが残る。

エスケープシーケンスについてちゃんと調べれば自分で除去スクリプトを書けると思うけど、今は調べたくない!

[unix][howto] tmuxでペインの内容をファイルに出力する

scriptコマンドが使えないので別解を探す。tmuxに使える機能があるのではないか。

検索すると pipe-pane コマンドを使う例がよく出てくるが、これもエスケープシーケンスまで記録してしまうようである。

少し不便だけれど、 capture-pane コマンドを使えばエスケープシーケンスなしに実行コマンドの内容をファイルに出力できた。ただし、scriptコマンドとは違い、実行済みの結果をキャプチャすることになる。tmux上で次を実行する。

% tmux capture-pane -p -S -1000 > sample.txt
  • -pオプションを指定することでキャプチャ結果が標準出力に出力される。省略するとtmuxのバッファに出力される。
  • -Sオプションでキャプチャ対象の先頭位置を指定する。-1000だとアクティブなペインに今表示されている一番上の行から1000行遡った行から下がキャプチャされる。省略するとペインに今表示されている部分だけがキャプチャされるみたい。

先頭位置を指定しないといけない所が不便。多めにキャプチャして不要な部分を後から削除するしかない。

もっとましな方法ないのかなあ。

本日のツッコミ(全2件) [ツッコミを入れる]

宮川 拓 [scriptとtmuxの組み合わせで行けそうな気がします。 1. tmuxで新しいペインを作って、先頭でscrip..]

小川 [ありがとうございます。tmuxでもうまく動きました。]


2016年04月14日(木) [長年日記]

[unix][howto] scriptコマンドにエスケープシーケンスを残さない

前回の続きを少しメモ。

まず、エスケープシーケンスというのは山程あって「全部を除去」というのは簡単にはできなさそう。除去するのではなく解釈すべきものもあるし。

で、

に書かれていたのだけれど、TERM変数に dumb を設定するというのはいい方法だと思った。こうしておくと各コマンドが余計なエスケープシーケンスを出力しないようになるので、scriptコマンドの出力ファイルも綺麗になる。

あと、日本語環境だとscriptコマンドが「スクリプトは XXXX年XX月XX日 XX時XX分XX秒 に開始しました」のようなメッセージを出力ファイル内に出力し、そこに改行が入っていたりして変な感じになる。英語のメッセージならそういうことはないので、LANG=C も設定した方がよさそう。


2016年04月15日(金) [長年日記]

[unix][howto] CentOS 7にSoftware CollectionsのYUMリポジトリをインストールする

Software CollectionsのリポジトリにはGCC 5など新しいバージョンのソフトウェアが用意されている。リポジトリは

# yum install centos-release-scl

でインストールできる。

にある説明だとsclの部分が大文字だけれど、変わったみたい。

まだパッケージは1つもインストールしていないけど、例えばGCC 5は devtoolset-4-gcc という名前のパッケージで用意されているみたい。

% yum info devtoolset-4-gcc
読み込んだプラグイン:fastestmirror
Loading mirror speeds from cached hostfile
 * base: ftp.tsukuba.wide.ad.jp
 * epel: mirror.premi.st
 * extras: ftp.tsukuba.wide.ad.jp
 * updates: ftp.tsukuba.wide.ad.jp
利用可能なパッケージ
名前                : devtoolset-4-gcc
アーキテクチャー    : x86_64
バージョン          : 5.2.1
リリース            : 2.2.el7
容量                : 26 M
リポジトリー        : centos-sclo-rh/7/x86_64
要約                : GCC version 5
URL                 : http://gcc.gnu.org
ライセンス          : GPLv3+ and GPLv3+ with exceptions and GPLv2+ with exceptions and LGPLv2+ and BSD
説明                : The devtoolset-4-gcc package contains the GNU Compiler Collection version 5.