気になる内容メモ about C++1z #3
static_assertのメッセージ省略
式を真であるか否かを確かめるだけの時にコンパイル時アサートを使う時、メッセージを一々書かなければならないのが面倒くさい。C++14まではマクロを用いて実質的な省略を実現していたが、C++1zではより規格的なコーディングで省略する事ができる。
下記はC++14。マクロを用いて、1st argumentsを文字列化したものをstatic_assertのメッセージとする事による実質的な省略。
#define STATIC_ASSERT(EXPR) static_assert(EXPR,#EXPR) #define A 1 #define B 1 int main() { constexpr unsigned int a=1; constexpr unsigned int b=1; STATIC_ASSERT(A==B); STATIC_ASSERT(a==b); }
C++1z。より規格的なコーディング。
#define A 1 #define B 1 int main() { constexpr unsigned int a=1; constexpr unsigned int b=1; static_assert(A==B); static_assert(a==b); }
様々なものが規格として成る事によって厳密化する事ができる。とても良い。
template template parameterにtypenameキーワードの使用を許可
template template parameterはC++14までclassキーワードしか使用できなかった。(コンパイラによってはサポートしていた)
C++1zではtypenameが規格的に使用できるようになる。
$ cat test.cpp #include<vector> template<template<class ...>typename Container> struct A{Container<unsigned int> a;}; int main() { A<std::vector> a; } $ g++ -std=c++0x test.cpp test.cpp:3:29: error: template template parameter requires 'class' after the parameter list template<template<class ...>typename Container> ^~~~~~~~ class 1 error generated.
このエラー内容が許可されるようになる。(paiza.ioを使おうと思ったが、規格対応した時の事を踏まえて...)
値を返す型特性クラスのエイリアステンプレート
C++14まではf
C++14
#include<type_traits> #define STATIC_ASSERT(EXPR) static_assert(EXPR,#EXPR) int main() { STATIC_ASSERT(std::is_array<int []>::value); }
C++1z
#include<type_traits> int main() { static_assert(std::is_array_v<int []>); }
個人的にはスコープ解決演算子を書いた方が明示的で視覚的に分かりやすい気がしないでもないが・・・。
std::begin、std::endのようなコンテナの要素情報にアクセスする非メンバ関数
自前の組み込み配列とコンテナを共通インタフェースで扱えるようにするため、std::empty、std::size、std::dataが実装されるとのこと。 iteratorヘッダで定義され、これらの関数は、constexpr関数として定義。これらの関数のうちコンテナ版は、戻り値の型がコンテナの定義に依存するためコンテナ内に定義されているメンバー関数に依存しているということになる。
C++14
#include<iostream> #include<array> #define SIZE(a) (sizeof(a)/sizeof(*(a))) int main() { std::array<unsigned int,5> ar{1,2,3,4,5,}; unsigned int ar1[]{1,2,3,4,5,}; for(unsigned int i=0; i<ar.size(); ++i)std::cout<<ar[i]<<std::endl; for(unsigned int i=0; i<SIZE(ar1); ++i)std::cout<<ar1[i]<<std::endl; }
C++1z
#include<iostream> #include<array> #include<iterator> int main() { std::array<unsigned int,5> ar{1,2,3,4,5,}; unsigned int ar1[]{1,2,3,4,5,}; for(unsigned int i=0; i<std::size(ar); ++i)std::cout<<ar[i]<<std::endl; for(unsigned int i=0; i<std::size(ar1); ++i)std::cout<<ar1[i]<<std::endl; }
ネストな名前空間の省略的記述法
// The name of a named namespace may be qualified. namespace A::B { typedef int I; } // is equivalent to: namespace A { namespace B { typedef int I; } }
書いている間に時間なくなってしまったので取り敢えずアップする。細かい点は修正、追記していく予定。