Skip to content

Instantly share code, notes, and snippets.

@plasma-effect
Last active January 6, 2016 09:45
Show Gist options
  • Save plasma-effect/4d6ff2f0edec0ce87c9c to your computer and use it in GitHub Desktop.
Save plasma-effect/4d6ff2f0edec0ce87c9c to your computer and use it in GitHub Desktop.
VC++ in VS2015

ブログにソースコード貼っつけるよりgistにマークダウンで書いたほうが圧倒的に楽なことに気づいた。

2015年7月20日にVisual Studio 2015がリリースされた。当然VC++も新しくなったわけだがそのうち新しく追加された機能を出来る限り毎日記事にしようと思う。 本日はそのpart01、constexprだ。

constexprはC++11で追加された機能で、現在のC++14では更にパワーアップしているのだが、Microsoftの脳みそが2011年から進んでないのでC++11版のconstexprを紹介する。

コンパイル時において定数式はその場で計算される。定数式とは例えば以下の様なもの。

int main(){
  const int v = 1 + 2;//明らかに3
  const int u = 3 * 5;//明らかに15
}

一方でコンパイル時に使える定数(以下コンパイル時定数)が存在する。定数式で初期化されているconst定数がそれ。上の例で言えばvもuもコンパイル時定数である。コンパイル時に使えるとは例えばtemplate引数に渡せる。

template<int N>struct test{
  static int get(){
    return N;
  }
};
 
int main(){
  const int v = 1 + 2;
  const int u = test<v>::get();
}

この例ではvはコンパイル時定数なのでtemplateクラスtestの引数に渡せる。一方でstaticメンバ関数getは定数式ではないのでuはコンパイル時定数でない定数である。この場合uはtemplate引数に渡せない。

変数に対するconstexprは変数がコンパイル時定数であることを保証する指定子である。型はあくまでconstであり、constexprではない。

int hoge(){
  return 0;
}
 
int main(){
  constexpr int v = 0;//OK
  constexpr int u = hoge();//NG
}

一方で関数に対するconstexprはその関数を定数式として扱えるようにする指定子である。constexpr関数の中身は実質的にreturn文一つでなければならない。

constexpr int hoge(){
  return 0;
}
constexpr int fact(int n){
  return n==0 ? 1 : n*fact(n-1);
}
 
int main(){
  constexpr int v = 0;//OK
  constexpr int u = hoge();//OK
  constexpr int w = fact(5);//OK
}

return文一つといっても条件演算子が使えるので関数型言語に慣れている人なら親しみを持てるのではないだろうか。

定数式とできるのは組み込み型がまず上げられるがユーザー定義でconstexpr定数、またはconstexpr関数に使えるクラスも作ることができる。定数式に使える型をリテラル型と言う。

リテラル型には組み込み型やその配列がまず考えられるが、それらを組み合わせたユーザー定義型でリテラル型となる条件は以下のとおり。
・デストラクタがトリビアル
・次のどちらかを満たす「aggregateである」「コピーでもムーブでもないconstexprコンストラクタ、またはtemplateなコンストラクタを持つ」
・staticでないメンバ変数が全てvolatileでもないリテラル型
例えば以下の様なクラスがリテラル型となる。

struct pair{
  int x_,y_;
  constexpr pair(int x=0,int y=0):x_(x),y_(y){}
  pair(pair const&)=default;
  pair(pair&&)=default;
  ~pair()=default;
};
 
int main(){
  constexpr pair p(0,1);
  constexpr int u = p.x_;
  constexpr int v = p.y_;
}

そういえば上のコードでわかるようにVS2015ではムーブコンストラクタもdefault宣言できるようになった。むしろ今までできなかったほうがおかしい。

リテラル型やconstexprに関する活用法はここでは書かない。様々な場所で論じられているのでそちらを参考にして欲しい。

参考ページ 中3女子でもわかる constexpr:http://www.slideshare.net/GenyaMurakami/constexpr-10458089
リテラル型クラスの条件、および「中3女子でもわかる constexpr」の訂正:http://boleros.hateblo.jp/entry/20130718/1374155184(http://boleros.hateblo.jp/entry/20130718/1374155184)
C++11の文法と機能(C++11: Syntax and Feature):http://ezoeryou.github.io/cpp-book/C++11-Syntax-and-Feature.xhtml#basic.types(http://ezoeryou.github.io/cpp-book/C++11-Syntax-and-Feature.xhtml#basic.types)

余談
VC++のconstexprについての各種検証してない。誰か頼みます(他人任せ)。

「VS2015の記事を見てたはずだがいつの間にかconstexprの記事になっていた」という意見が出た。VC++固有の機能の記事なんて俺が書けるわけ無いだろ!!!!

2015年7月20日にVisual Studio 2015がリリースされた。当然VC++も新しくなったわけだがそのうち新しく追加された機能を出来る限り毎日記事にしようと思う。 本日はそのpart02、ユーザー定義リテラルだ。

ある型の一時変数を作るのにわざわざ関数を使いたくはないという時があったりなかったりする。例えば複素数値型など。

struct complex{
  int re_,im_;
  constexpr complex(int re=0, int im=0):re_(re),im_(im){}
  complex(complex const&)=default;
  complex(complex&&)=default;
  ~complex()=default;
};
 
int main(){
  complex v = complex(0,2);//2iって書きたい
}

100uでunsigned int型の100を表すようにユーザー定義のリテラルを使いたい。 operator""でそのようなユーザー定義のリテラルを作ることができる。

struct complex{
  int re_,im_;
  constexpr complex(int re=0, int im=0):re_(re),im_(im){}
  complex(complex const&)=default;
  complex(complex&&)=default;
  ~complex()=default;
};
 
complex operator"" _i(unsigned long long int v){
  return complex(0, v);
}
 
int main(){
  complex v = 2_i;//complex(0, 2);
}

ユーザー定義リテラルにはいくつか成約がある。まず引数の型にはunsigned long long intやlong doubleといった一部の型しか使えない。

int operator"" _hoge(unsigned long long int v){//OK
  return static_cast<int>(v);
}
int operator"" _piyo(int v){//NG
  return static_cast<int>(v);
}
 
int main(){}

また_(アンダーバー)から始まらないリテラルは予約されてるので使うと色んな人に怒られる。コンパイラにも怒られる。

int operator"" hoge(unsigned long long int v){
  return static_cast<int>(v);
}//コンパイルは通るが警告が出る
 
int main(){}

あと規格的には""と_の間に空白文字(スペースなど)が必要…らしい。別にMSVCでもgccでもclangでもスペース入れなくても通るんだから気にする必要とかないんじゃないのかこれ

unsigned long long intの他に使える型を紹介する。まずはlong double

int operator"" _to_int(long double d){
  return static_cast<int>(d);
}
 
int main(){
  int v = 2.0_to_int;
}

char const*

#include<utility>
int operator"" _hoge(char const*, std::size_t s){
  return s;
}
 
int main(){
  int v = "test"_hoge;
}

あとはwchar_tとかそこら辺である。

ユーザー定義リテラルでは基本的にtemplateが使えない。ただしvariadic templateを使用できる唯一の例が存在する。

template<char... Cs>struct string_t{};
template<char... Cs>string_t<Cs...> operator"" _hage(){
  return string_t<Cs...>{};
}
 
int main(){
  auto x = 12345_hage;//string_t<'1', '2', '3', '4', '5'>
}

この場合引数は付けない。またunsigned long long intのみに対応する。

参考
本の虫 ユーザー定義リテラルのすべて:http://cpplover.blogspot.jp/2012/02/blog-post_16.html
C++11の文法と機能(C++11: Syntax and Feature):http://ezoeryou.github.io/cpp-book/C++11-Syntax-and-Feature.xhtml#over.literal

余談
今後こっちに記事を書いていこうと思います。ブログとはなんだったのか。

俺が言いたいのは「VS2015は便利だから使おうね」ではない。「2015年にVC++2005とかVC++2008とか使うな」である。最低限VS2013以降にしてくれ。

2015年7月20日にVisual Studio 2015がリリースされた。当然VC++も新しくなったわけだがそのうち新しく追加された機能を出来る限り毎日記事にしようと思う。 本日はそのpart03、返り値autoだ。

templateを使ってるとたまに関数の返り値を指定したくない時がある。極端な例だが次のクラスなど。

struct add_t{
	template<class Lhs,class Rhs>Lhs operator()(Lhs lhs, Rhs rhs)const{
		return lhs + rhs;
	}
};

int main(){
	add_t add{};
	auto v = add(1, 2.0);//vはint型!
}

int型とdouble型のoperator+の返り値はdouble型に決まっているのだがこの場合add_t::operator()の返り値がLhsに依存しているためint型になってしまっている。今までも返り値の後置記法とdecltypeで対処はできたのだが

struct add_t{
	template<class Lhs,class Rhs>auto operator()(Lhs lhs, Rhs rhs)->decltype(lhs + rhs) const{
		return lhs + rhs;
	}
};

int main(){
	add_t add{};
	auto v = add(1, 2.0);//vはdouble型!
}

同じ式を2回書いている。片方を書き換えた時もう片方を書き換え忘れたら悲劇が起きる。

これからは単純にautoだけでよい。するとreturn文の中身から型を推論してくれる。

struct add_t{
	template<class Lhs,class Rhs>auto operator()(Lhs lhs, Rhs rhs)const{
		return lhs + rhs;
	}
};

int main(){
	add_t add{};
	auto v = add(1, 2.0);//vはdouble型!
}

上の例のように、特にtemplateを使うときにこの機能は真価を発揮する。

まるで銀の弾丸のようなこの機能だが、当然銀の弾丸ではない。原理としては変数に対するautoと同じなので色々成約がある。まずそのままだと参照でない。

auto hoge(int& x){//int&->int
	return x;
}
auto&& piyo(int& x){//int&->int&
	return x;
}
int main(){
	int x{10};
	hoge(x)=5;//NG
	piyo(x)=5;//OK
}

また複数のreturn文が存在するときはそれらは全て同じ型でなくてはならない。実用上では最初に現れたreturn文の型と相反するreturn文が存在してはいけない。

auto hoge(int x){
	if(x > 0)
		return true;
	else
		return false;
}

auto piyo(int x){
	if(x > 0)
		return true;
	else
		return 0;//NG
}

逆に言えば最初のreturn文で一応返り値の型は推論されているわけである。つまりconstexprでなければ再帰が書ける。

auto fact(int n){
	if(n == 0)
		return 1;
	else
		return n * fact(n-1);//OK、この段階でfactはint->intと推論されている
}

int main(){}

なぜconstexprだと書けないのかというとconstexprではreturn文が一つなのでその段階では返り値の型がわかってない(=return文に現れてはいけない)ため。

あと返り値autoを多用するとぱっとコードを見た時返り値の型がわからなくなる。VS2015を前提としてるのでインテリセンスがあるのだが非template関数のintやdoubleはそのまま書いたほうがいいような気もする。

参考
巻末: C++14の新機能:http://ezoeryou.github.io/cpp14-appendix/#return_type_deduction

余談
生ポインタは危ないからスマートポインタを使おうね(boost使うとコンパイル時間がブーストするからVS2013以降を使えの意)。

さらに余談
投稿したあとに気づいたのだが4つ目のコード(の9行目をコメントアウトしたもの)がインテリセンスでは引っかかるのにコンパイルは通るコードになっている。

オーバーロードされた関数の関数ポインタの取り方とかついさっき知った。

2015年7月20日にVisual Studio 2015がリリースされた。当然VC++も新しくなったわけだがそのうち新しく追加された機能を出来る限り毎日記事にしようと思う。 本日はそのpart04、ジェネリックラムダと汎用ラムダキャプチャーだ。

今までラムダは引数の型は指定しなくてはならなかった。

#include<algorithm>

int main()
{
	int X[] = { 0,1,2,3,4 };
	int x = std::count_if(std::begin(X), std::end(X), [](int v) {return v % 2 == 0;});
}

基本的にそれで別にいいのだがtemplateを使う時などに柔軟に対処したい時がある。 例えばC++においてはオーバーロードされた関数の関数ポインタを取るには単純な手段は取れない(参考:Cry’s Diary オーバーロードされた関数へのポインタ / 関数テンプレートへのポインタ)。 STLなどで使う場合は関数ポインタでなくてもよい(関数オブジェクトであれば渡せる)が

#include<utility>
namespace detail {
	int twice(int n) {
		return 2 * n;
	}

	double twice(double d) {
		return 2.0 * d;
	}
}

struct {
	template<class T>auto operator()(T v)const {
		return detail::twice(v);
	}
}const twice;

template<class Func, class... Ts>auto function_call(Func func, Ts&&... args) {
	return func(std::forward<Ts>(args)...);
}

int main(){
	auto v = function_call(twice, 2);//OK
	auto u = function_call(twice, 1.0);//OK
}

クラスを自作する等のまどろっこしい手順を取らなければならない。ラムダでもtemplateのようなものを使いたい。

これからはautoを使うことでそのようなことができる。

#include<utility>
namespace detail {
	int twice(int n) {
		return 2 * n;
	}

	double twice(double d) {
		return 2.0 * d;
	}
}
template<class Func, class... Ts>auto function_call(Func func, Ts&&... args) {
	return func(std::forward<Ts>(args)...);
}

int main(){
	auto twice = [](auto v) {return detail::twice(v);};
	auto v = function_call(twice, 2);//OK
	auto u = function_call(twice, 1.0);//OK
}

当然複数の引数でautoを書けばそれぞれでジェネリックになる。

int main() {
	auto add = [](auto x, auto y) {
		return x + y;
	};
	auto v = add(1, 2.0);//OK
}

今までラムダ式のキャプチャーはコピーキャプチャーと参照キャプチャーの2つしかなかった。

int main(){
	int x{};
	auto func = [=]{//コピーキャプチャー
		++x;//NG、xは変更不能
	};
	func();
	
	auto func2 = [&]{//参照キャプチャー
		++x;//OK、xは1になる
	};
	func2();

	auto func3 = [=]()mutable{//mutableなコピーキャプチャー
		++x;//OK、ただし元のxに変化はない
	};
	func3();
	
	auto func4 = [&x]{//xのみを参照キャプチャー
		++x;//OK、xは2になる
	};
	func4();
}

これはクラスのメンバをキャプチャーするときに問題がある。クラスのメンバ関数内でのラムダ式のキャプチャーはthisとローカル変数のみをキャプチャーしている。

struct test{
	int x;
	auto get_closure(){
		return [=]{
			return x;
		};
	}
	auto get_closure2(){//closureは次と同じ
		return [this]{
			return this->x;
		};
	}
};

int main(){}

この時thisの寿命によって問題が発生したりする。具体的にはthisを指す変数が定義されたスコープを抜けたあとに呼びだそうとした場合は未定義動作となる。

新しいラムダキャプチャーでは変数宣言かのように指定できる。

struct test{
	int x;
	auto get_closure(){
		return [x = x]{
			return x;
		};
	}
};

int main(){
	int m=0;
	auto func = [z = m + 2]{
		return z;
	};
}

std::moveや参照なども当然使える。

参考
1.3 汎用lambdaキャプチャー(Generalized Lambda-capture)http://ezoeryou.github.io/cpp14-appendix/#init_captures
1.4 ジェネリックlambdahttp://ezoeryou.github.io/cpp14-appendix/#generic_lambda

余談
最新のC++の機能を使い尽くしてコード書いたゲームとか一回ぐらい作ってみたいねぇ

書くネタが尽きてきた。こことにらめっこしながら書いている。

2015年7月20日にVisual Studio 2015がリリースされた。当然VC++も新しくなったわけだがそのうち新しく追加された機能を出来る限り毎日記事にしようと思う。 本日はそのpart05、constexpr化した標準ライブラリだ。

一部の標準ライブラリはpart01で紹介したconstexprに対応した。今回はそれを紹介していく。

まずはcomplex

#include<complex>

int main() {
	constexpr std::complex<int> x{ 1,2 };
	constexpr std::complex<int> y{ 2,2 };

	constexpr bool a = x == y;
	constexpr bool b = x != y;
	constexpr bool c = x.real() == y.real();
	constexpr bool d = x.imag() == y.imag();
}

他にもTy_とcomplexのoperator==などがconstexprされている。一方でoperator+などはconstexpr化されていない。注意。

次にarray

#include<array>

int main() {
	constexpr std::array<int, 4> v{ 1,2,3,4 };
	
	constexpr int v0 = v[0];
	constexpr int v1 = v[1];
	constexpr int v2 = v[2];
	constexpr int v3 = v[3];
}

元からAggregateだし今更感はある。

chrono

#include<chrono>

int main() {
	constexpr std::chrono::milliseconds sen{ 1000 };
	constexpr std::chrono::milliseconds hyaku{ 100 };
	
	constexpr auto senhyaku = sen + hyaku;
	constexpr auto kyuhyaku = sen - hyaku;
}

他にはoperator==などもconstexprになっている。

initializer_list

#include<initializer_list>

int main() {
	constexpr std::initializer_list<int> lis{};
	
	constexpr auto b = lis.begin();
	constexpr auto e = lis.end();
	constexpr auto s = lis.size();
}

デフォルトコンストラクタがconstexprになった。

utility

#include<utility>

int main() {
	constexpr int v{ 10 };
	constexpr int u = std::forward<int const&>(v);

	constexpr std::pair<int, double> p{ 1,2.0 };
	constexpr auto a = p.first;
	constexpr auto b = p.second;
	constexpr auto p2 = std::make_pair(1, 2.0);
	constexpr bool x = p == p2;
}

他にはstd::move、std::move_if_noexceptもconstexprに。

tuple

#include<tuple>

int main() {
	constexpr std::tuple<int, double, short> t{ 1,2.0,3 };
	constexpr auto x = std::get<0>(t);
	constexpr auto y = std::get<1>(t);
	constexpr auto z = std::get<2>(t);
}

functional

#include<functional>

int main() {
	constexpr std::plus<> plus{};
	constexpr auto x = plus(1, 2);
}

参考
N3302http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3302.html
N3469http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3469.html
N3470http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3470.html
N3471http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3471.html
N3789http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3789.htm

余談
並列処理関連がさっぱりなので今回のシリーズでは触れない予定

VC++のstd::make_index_sequenceを再帰深度線形オーダーで実装したやつ出てこい、説教してやる。

2015年7月20日にVisual Studio 2015がリリースされた。当然VC++も新しくなったわけだがそのうち新しく追加された機能を出来る限り毎日記事にしようと思う。 本日はそのpart06、noexceptだ。

かつてC++の規格には動的例外指定という機能があった。いや今でもあるのだが今ではdeprecatedである。外に投げうる例外の型を指定する機能だ。

int add(int x, int y)throw() {//例外は許されない
	return x + y;
}

class div_zero_exception{
public:
	div_zero_exception(){}
};

int div(int x, int y)throw(div_zero_exception) {//div_zero_exceptionのみが許される
	if (y == 0)throw div_zero_exception();
	return x / y;
}

int main(){}

これをMSVCでコンパイルしたときの警告を見ればわかるだろうがMSVCではthrowの中身なんて空か否かしか見ていない。次のコードを実行すればそのことがわかる。

#include<iostream>
namespace test {//divがグローバル名前空間(おそらくC由来の標準ライブラリ)で衝突したので
	class div_zero_exception {
	public:
		div_zero_exception() {}
	};

	int div(int x, int y)throw(div_zero_exception) {//div_zero_exceptionのみが許されるはずだった
		if (y == 0)throw 1;
		return x / y;
	}
}

int main(){
	try {
		test::div(1, 0);
	}
	catch(int){
		std::cout << "test" << std::endl;
	}
}

規格ではtest::divを呼び出したときにstd::terminateが呼ばれることになっている。gccやclangでは律儀にstd::terminateが呼ばれる。だが多くの実装で動的例外指定はなかったことされていたらしい。

一方throw()の時はその関数は例外を外に出さない、言い換えれば例外が発生したらその場でstd::terminateが呼ばれることが保証される。要するにこの使い方に関してはとても便利だったということだ。

そしてそれ専用の文法が追加された、それがnoexceptである。

#include<type_traits>
void test()noexcept{}//例外を投げないことを保証
void test2()noexcept(false){}//例外を投げるかもしれない
void test3()noexcept(true){}//例外を投げないことを保証
template<class T>void test4(T)noexcept(std::is_same<int, T>::value){}//Tがintなら投げないことを保証、そうでない場合投げるかもしれない

noexceptだけなら例外を投げないことを保証し、noexcept(定数式)なら定数式を評価してtrueになら投げない、falseなら投げうる。 これのいいところは上でもわかるようにtemplate引数によって容易に指定を変えることができる点だ。当然メタプログラミングの技術を使えばより複雑な動きができる。

なお、noexcept指定は外に例外を投げないことを指定するだけなので内部で例外を発生させてtry-catchで対処する場合はなんら問題ない。

void test()noexcept{
	try{
		throw 1;
	}
	catch(int){}
}

int main(){
	test();
}

さらに演算子としてnoexceptも追加された。式を渡して例外を投げうる式を含まないならtrue、含むならfalseを返す。

void test()noexcept(false){}
void test2()noexcept{}
void test3(){}

int main() {
	static_assert(noexcept(1 + 2), "1 + 2");//明らかに例外を投げない
	static_assert(noexcept(throw 1), "throw 1");//明らかに例外を投げている
	static_assert(noexcept(test()), "test()");//noexcept(false)が指定されている
	static_assert(noexcept(test2()), "test2()");//noexceptが指定されている
	static_assert(noexcept(test3()), "test3()");//何も指定されてないため投げられるかもしれない
	static_assert(noexcept(noexcept(test())), "noexcept(noexcept(test()))");//noexcept演算子自体は例外を投げない
}

上の例でわかるようにnoexceptは定数式であり、したがって例外を投げない。またnoexceptの中身は評価されない。 これで引数として渡された関数オブジェクトが例外を投げうるかどうかで処理を変えることもできる。

参考
C++11の文法と機能(C++11: Syntax and Feature)noexcept演算子http://ezoeryou.github.io/cpp-book/C++11-Syntax-and-Feature.xhtml#expr.unary.noexcept
C++11の文法と機能(C++11: Syntax and Feature)例外指定http://ezoeryou.github.io/cpp-book/C++11-Syntax-and-Feature.xhtml#except-spec

余談
noexcept指定した関数内で例外が発生した場合の挙動だが、VS2015の場合デストラクタが呼ばれる保証がないそうだ(https://msdn.microsoft.com/en-us/library/dn956976.aspx参照)。

そういやサンプルコードのライセンス考えるの忘れてた。自由に使っていいし自由に改変していいし自由に転載していい。

2015年7月20日にVisual Studio 2015がリリースされた。当然VC++も新しくなったわけだがそのうち新しく追加された機能を毎日紹介してきた。 本日は最終回、まだ紹介してない機能を少しずつ紹介していく。

通常、文字列リテラルは""で囲む。この場合実装依存のエンコードになる。
これをUTF-8、UTF-16、UTF-32に指定したい場合はそれぞれu8""、u""、U""で囲む。
またUTF-16、UTF-32用にchar16_tとchar32_tという型が追加された。

int main() {
	char const str[] = u8"1234";
	char16_t const str2[] = u"1234";
	char32_t const str3[] = U"1234";
}

関数内でその関数名をconst char[]で取得できるようになった。

const char* func(){
	return __func__;//__func__でその関数名と同じ文字列になる
}

int main() {
	const char* str = func();
}

2進数で整数リテラルを書けるようになった。また数値リテラルで桁を区切れるようになった。

int main() {
	int x = 0b0000'1111;
	int y = 0b0011'0011;
	int z = 0b0101'0101;
}

関数にdeprecatedを指定できるようになった。MSVCではそのような関数が呼び出されようとするとコンパイルエラーになる。

[[deprecated]]void depre(){}

int main() {
	depre();
}

template template parameterでtypenameと書けるようになった。

template<template<class>typename T>struct T{};

template<class>struct U{};

int main() {
	T<U> x{};
}

std::integral_constantにoperator()が追加された。

#include<type_traits>

int main() {
	std::integral_constant<int, 4> x{};
	int y = x();
}

chronoにユーザー定義リテラルが追加された。

#include<chrono>

int main() {
	using namespace std::chrono_literals;
	constexpr auto hyaku = 100ms;
	constexpr auto nihyaku = 200s;
	constexpr auto t = hyaku + nihyaku;
}

文字列をstd::stringにするユーザー定義リテラルが追加された。

#include<string>

int main() {
	using namespace std;
	auto str = "12345"s;
}

""で囲む文字列を扱うためのstd::quotedが追加された。

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

int main() {
	using std::operator""s;
	auto str = "test"s;
	std::cout << std::quoted(str) << std::endl;
	
	auto str2 = R"("Hello World")"s;
	std::stringstream ss{};
	ss << str2;
	ss >> std::quoted(str2);
	std::cout << str2 << std::endl;
}

フリー関数としてstd::sizeとstd::emptyとstd::dataが追加された。

#include<vector>

int main() {
	std::vector<int> vec = { 0,1,2 };
	int s = std::size(vec);
	bool e = std::empty(vec);
	auto d = std::data(vec);
}

参考
C++11の文法と機能(C++11: Syntax and Feature)エンコード方式:http://ezoeryou.github.io/cpp-book/C++11-Syntax-and-Feature.xhtml#encoding-scheme
巻末: C++14の新機能 1.1 二進数リテラル(binary literal):http://ezoeryou.github.io/cpp14-appendix/#binary-literal
巻末: C++14の新機能 1.2 桁区切り(digit separator):http://ezoeryou.github.io/cpp14-appendix/#digit-separators
巻末: C++14の新機能 1.10 [[deprecated]]:http://ezoeryou.github.io/cpp14-appendix/#deprecated_attribute
本の虫 2014-05-pre-Rapperswil-mailingのレビュー: N4040-N4051:http://cpplover.blogspot.jp/2014/08/2014-05-pre-rapperswil-mailing-n4040.html
Faith and Brave - C++で遊ぼう C++14 quotedマニピュレータ:http://faithandbrave.hateblo.jp/entry/20131108/1383886265

終わりに
元々ブログの広告を消すために始まったこの企画だったが途中からGistに移った。 普段から最新のC++を追う層からしたら知ってるようなことばかり書いたが、 VS2015では何が使えて何が使えないのかを自分の中で整理することができた。 ここまで読んで下さった方々には感謝の意を伝えたい。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment