尋常でないもふもふ

a software engineer blog

C++糞コンパイルエラー集

わかりにくいコンパイルエラーに悩まされて時間を無駄にすることがたびたびあり、6度目くらいでカッとなって記事にすることにした。順次追加していく。

Member reference base type 'User *const' is not a structure or union

以下は std::vector の中から指定の name に一致するユーザーの id を取得するサンプルコード。

int findByName(std::vector<User*> users, const std::string& name)
{
    auto user = std::find_if(users.begin(), users.end(), [name](User* u)
    {
        return u->getName() == name;
    });
    return user->getId(); // ここでエラー
}

正しいコードはこちら。
std::find_if の戻り値がイテレータであることを知らずにオブジェクトだと誤解してるとハマる。ポインタにキャストすると値が取れる。

int findByName(std::vector<User*> users, const std::string& name)
{
    auto itr = std::find_if(users.begin(), users.end(), [name](User* u)
    {
        return c->getName() == name;
    });

    if (itr == users.end())
    {
        return -1;
    }
    else
    {
        return (*itr)->getId();
    }
}

id を返すコードだったため余計にエラー文がわかりづらい表現になっていた。もし User* 自体を返すコードだったら以下のようなエラー文になる。

No viable conversion from returned value of type 'std::__1::__wrap_iter<User**>' to function return type 'User *'

wrap_iter<User**> となるためイテレータ型であることに早期に気づいたかもしれない。

MacにPlantUMLをいれる

クラス図やシーケンス図の UMLMarkdown のようにテキストエディタで記述できる PlantUML の環境設定。

必要なもの

動作に必要なのは4つ。Java 環境とかここ2〜3年必要なかったし正直もういれたくないんだけど、このためだけにわざわざインストールすることにした。

Homebrew Cask をいれてない場合は Cask を使えるようにしておく。

$ brew tap caskroom/cask

Java

Java がないと PlantUML は動かない。

$ brew cask install java

Oracle の Java8 がインストールされた。

$ java -version
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b16, mixed mode)

PlantUML

PlantUML も Homebrew でインストール。

$ brew install plantuml
$ plantuml -version
PlantUML version 8048 (Fri Sep 30 02:04:02 JST 2016)
(GPL source distribution)
Java(TM) SE Runtime Environment
Java HotSpot(TM) 64-Bit Server VM
1.8.0_112-b16
Mac OS X
UTF-8
Processors: 4
Max Memory: 3,817,865,216
Total Memory: 257,425,408
Free Memory: 249,354,984
Used Memory: 8,070,424
Thread Active Count: 2

The environment variable GRAPHVIZ_DOT has been set to /usr/local/opt/graphviz/bin/dot
Dot executable is /usr/local/opt/graphviz/bin/dot
Dot version: dot - graphviz version 2.38.0 (20140413.2041)
Installation seems OK. File generation OK

Atom Editor

Atom エディタも Cask からいれてる。

$ brew cask install atom
$ atom --version
Atom    : 1.12.6
Electron: 1.3.9
Chrome  : 52.0.2743.82
Node    : 6.5.0

使い方

あとは plantuml-viewer プラグインいれて、拡張子が .pu のファイルつくって編集するだけ。
Atom のショートカットキーは Control + Option + PMarkdown エディタとほぼ同じ使い勝手。 チートシートPlantUML Cheat Sheet - Qiita

迷いがちな英語の変数・関数名まとめ

新しいプロジェクトはじめたり、新機能開発したりすると調べなおしたりすることが多いので順次追加していく。

類義語

お金・資源などが足りないとき

  • insufficient [形容詞]
    • メモリ不足 (insufficient memory) とか資源不足 (insufficient resource`) とか
    • そもそも形容詞のため下の2つとは使い方が異なる
  • shortage [名詞]
    • 数値などの具体的で定量化できるものが不足
    • ただし全くないという場合には使えない
  • lack [動詞・名詞]
    • 経験/優しさなどの抽象的なものが不足

  • amount [動詞・名詞]
    • 抽象的な量、多さ
  • quantity [名詞]
    • 具体的な数、数値として表せるもの

買う

  • buy [動名詞]
    • 口語的な用語
    • お金の支出に重きをおいている
  • purchase [動詞・名詞]
    • フォーマルな用語
    • 購入処理のやり取りに重きをおいている
    • 関数名やAPI名としてこっちのが適切

最大値・限界値

  • max [名詞]
    • 最大限、最高限度、最高値、最大値
    • 数学的には何個かの数があってその中でもっとも高いものを max で表す (max関数が有名)
  • limit [名詞]
    • 最高限度、最大限度、制限、限界、上限

RPG の最大レベルとか所持金の限度額とかで max 使うのか limit 使うのかは判断が難しい
考え方としてシステム的に超えたら NG というケースで定義する変数は limit が適切
max は過去最高記録のスコアとかで使うべき、あと min との対比で定義したいとき

対義語

  • approvedecline
    • 同意する, 賛成する, 承認する ⇔ 辞退する, 断る
    • ネットゲームのフレンド申請でつかうのに適切な丁寧な用語
      • Super Mario Run でもこの表現を使っている
    • ただしニュアンス次第
      • League of Legends のチャンピオントレードでは acceptdecline が使われてる
  • acceptrefuse
    • 受諾する ⇔ 拒否する
    • 直接的な表現にしたいとき
  • allowdeny
    • 許可する ⇔ 拒絶する
    • ネットワークのアクセス権や認証系でつかう用語
    • deny は真実ではない/間違っているという否定の文脈でつかわれる
  • successfailure
    • 成功 ⇔ 失敗
    • ちなみに OK ⇔ NG は成立しない
      • NG は和製英語
      • 英語的には通用しないけどシンプルだし簡易な記述としてはアリだと思う
    • HTTP 関連の用語として使いたい場合は SuccessError の方が対として適切
      • 200 系 → Success
      • 400 系 → Client Error
      • 500 系 → Server Error
  • malefemale
    • 男性 ⇔ 女性
    • manwoman は使わない
    • 性別は sex ではなく gender を使う