4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

C++のtemplateとdefine, constexprの使い分け

Posted at

UE4のエンジンを眺めていると、templateとdefine, constexprの全てが使われていて、混乱していたので整理がてらまとめてみる。
間違っているのでツッコミ大歓迎!

全てコンパイル時実行 かつ templateが型安全 なのに何故defineを使うのか???
って思った方の手助けになればと思います。

各種機能概要

template

テンプレート引数を受け取り、引数の情報に従って関数やクラスを生成する機能。
使いこなすことができると悪いことも色々できる。
他2つの機能より抜きんでているイメージ。

sampleTemplate.cpp
// define template.
template <typename T>
void Func(T arg)
{
    // do something.
}

// instance template.
Func<int>(5);
Func<double>(1.5);

メリット

  • 型に対して安全。
  • 特殊化によって特定にテンプレート引数の時に挙動を変えられる。
  • type_traitsが使える。(C++11)

デメリット

  • 特になし。

他にもデフォルトテンプレート引数とかエイリアステンプレートとかの使い方があるけど、今回は関係ないので割愛する。

define

プリプロセッサ命令
マクロを定義したり、シンボルを定義したりして、コンパイル時の制御をすることができる。
昔ながらの機能ってイメージ

sampleDefine.cpp
// This is symbol.
# ifndef DEBUG
    #define DEBUG
# endif
# undef DEBUG

// This is macro.
# define FUNC(x) (x)*(x)

メリット

  • 関数の生成と定数の定義のどちらでも使える。
  • シンボルの再定義ができる。

デメリット

  • 文字列として扱われるため、型の情報を無視する。
  • マクロ展開時に関数の副作用が複数回発生することがある。

constexpr

c++11で追加された定数、関数をコンパイル時に計算する機能。
とりあえず定数定義ならこれ使っておけって印象。

sampleConstexpr.cpp
constexpr int KB = 1024;
constexpr int POW(int x) { return x * x; }
constexpr int SIZE = POW(KB);
int hogeArray[SIZE];

メリット

  • 記述が容易。
  • constexpr関数はコンパイル時でも実行時でも使える。

ここで疑問

Question

templateが型安全なのに、なぜ今だにdefineを使うのか?

Answer

defineでしかできないことがある。

defineにしかできないこと

①シンボル定義

変数名を変えることができる。
##がキモ

②他プリプロセッサ命令に文字列を与えることができる。

defineはプリプロセッサだからできること。
例としてincludeにマクロ展開したファイル名を与える。

changeIncludeFile.cpp
// each macro needs "_INNER" macro, because it expands args macros at first.
# define TO_STR(x) TO_STR_INNER(x)
# define TO_STR_INNER(x) #x
# define SAMPLE_FILE(suffix, file) SAMPLE_FILE_INNER(suffix, file)
# define SAMPLE_FILE_INNER(suffix, file) suffix##file

# include TO_STR(SAMPLE_FILE(sample, Define.h)) // #include "sampleDefine.h"

結論

基本的にはtemplateやconstexprが型安全なのでガンガン使ってよさそう。
定数定義やマクロくらいの関数といった簡単なこと→constexpr
型分岐やコンテナ実装等のちょっとリッチなことをする→template
defineでしかできない→define

4
4
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?