読者です 読者をやめる 読者になる 読者になる

ゆとりーなの日記

日記的な事を書いて行くと思はれる

MSVC10とC++11

これはC++11 Advent Calendar 2011 : ATNDの22日目の記事です。
さてさて、私はWindows系男子であるのでWindows環境でのC++コンパイラといえばまず最初に挙がってくるであろうMSVCとC++11の話をしようかなと思うのは割と自然な流れでして。まぁMSVC10がどのくらいC++11に対応しているかは色んな所に表があったりするので今回は実装されてはいるもののなんかあるぞみたいな物達についてほげほげと書いていくわけです。今回貼るコードはMSVC10ではコンパイルが通らない子達です。

言語使用編

ラムダ

ラムダ自身のひとつ外側のスコープの変数しか指定キャプチャすることが出来ません。

int main() {
  int a;
  [&a] {
    [&a] {
    };
  };
  return 0;
}

条件を満たしても函数ポインタに変換することが出来ません。

int main() {
  void (*p)() = [] {};
  return 0;
}
decltype

decltypeをネストした感じに使うことが出来ません。

struct hoge {
  typedef int type;
};

int main() {
  hoge h;
  decltype(h)::type i;
  return 0;
}
暗黙のムーブ

暗黙のムーブコンストラクタ等が生成されないようです。

#include <memory>
#include <utility>
#include <vector>

struct hoge {
  std::unique_ptr<int> ptr;
};

int main() {
  hoge h;
  std::vector<hoge> v;
  v.push_back(std::move(h));
}
default/delete指定

MSDNのクラス宣言の項を見るとさりげなくコピーコンストラクタがdelete指定されていたりする表記があったりするのですが、実際にはこの構文をMSVC10で使うことは出来ません。

struct hoge {
  hoge(const hoge &rhs) = delete;
};

明示的な型変換

こちらもMSDNのクラス宣言の項で使用例がありますが、この構文もMSVC10で使うことは出来ません。

struct hoge {
  explicit operator bool() const {
    return true;
  }
};

ライブラリ編

vector

emplace系のメンバ函数を本来の用途でほぼ使うことが出来ません。

#include <vector>

struct hoge {
  hoge(int i, int j) {}
};
 
int main() {
  std::vector<hoge> v;
  v.emplace_back(0, 1);
  return 0;
}
initializer_list

ヘッダ自体はありますが多くの場合インクルードしただけでコンパイルエラーを引き起こし、万が一起こさなくても殆ど使うことが出来ません。

#include <initializer_list>
 
int main() {
  std::initializer_list<int> i = {0, 1, 2};
  return 0;
}
random

uniform_int_distributionで負の数が絡むと下限の値が出現しなくなるようです。

// 註:このコードはコンパイルは通ります
#include <random>
#include <iostream>

int main() {
  std::mt19937 d;
  std::uniform_int_distribution<> dis(-2, 3);
  for (int i = 0; i < 100; ++i) {
    std::cout << dis(d) << std::endl;
  }
  return 0;
}

uniform_int、variate_generatorはC++11にはないので移植性がなくなります。

// 註:このコードはMSVCだとコンパイルは通ります
#include <random>
#include <iostream>

int main() {
  std::mt19937 d;
  std::uniform_int<unsigned int> dis(0, 3);
  std::variate_generator<std::mt19937, std::uniform_int<unsigned int>> v(d, dis);
  for (int i = 0; i < 100; ++i) {
    std::cout << v() << std::endl;
  }
  return 0;
}
type_traits

operator boolがないのでboolに変換することが出来ません。

#include <type_traits>

int main() {
  bool b = std::is_void<void>();
  return 0;
}
exception_ptr

色々と足りないものがあり、一部の構文が通りません。

#include <exception>

int main() {
  std::exception_ptr ptr;
  if (ptr) {
  }
  return 0;
}
limits

constexprが実装されていないのでnumeric_limitsのメンバ函数の使用できる状況に制限が生じます。

#include <limits>

int main() {
  int a[std::numeric_limits<char>::max()];
  return 0;
}

取り敢えずぱっと思いついたのはこれくらい

なのでここらへんで終わりということにしておきます。

次回は

id:tt_clownさんです。

追記

Advent Calendarで残念なところ列挙するだけなのはどうなのって感じの反応を受けて、それもそうだなと思ったので時期バージョンVisualStudio11のDeveloper Previewも公開されていることですしどのくらい改善されているのかも調べてみました。

ラムダ

ラムダ式周りは通るようになっているようです。

vector

emplace系のメンバ函数が使えるようになっています。

random

uniform_int_distributionで負の数が絡んでも下限の値が出現するようです。

type_traits

operator boolが追加されたようで、boolに変換することが出来るようになっているみたいです(constexprは相変わらずないので定数式としては使えません)。