##(ダブルハッシュ)はプリプロセッサディレクティブで何をしますか?


91
#define DEFINE_STAT(Stat) \
struct FThreadSafeStaticStat<FStat_##Stat> StatPtr_##Stat;

上記の行はUnreal4からの抜粋であり、Unrealフォーラムで質問できることはわかっていますが、これは一般的なC ++の質問であり、ここで質問する必要があると思います。

最初の行がマクロを定義していることは理解していますが、C ++のプリプロセッサのシェナニガンに精通していないため、そこで迷子になっています。ロジックによると、バックスラッシュは宣言が次の行に続くことを意味します。

FThreadSafeStaticStatはテンプレートに少し似ていますが、そこには#があり、C ++ではこれまでに見たことのない構文があります。

誰かがこれが何を意味するのか教えてもらえますか?Unreal 4にアクセスできない可能性があることは理解していますが、それは私が理解していない構文にすぎません。


6
とりわけcppreferenceの##演算子について読むことができます
Cubbi 2014

1
##連結演算子と呼ばれることもあります。
dyp 2014

1
ああ、それはかなりクールです!それはかなり多くを説明します、ありがとう。しかし、なぜstructキーワードが使用されるのですか?この行は変数定義のように見えます
DavidColson 2014

1
struct紹介精巧な型指定子を私の知る限り。
dyp 2014

2
2つの前処理トークンを組み合わせて別のトークンを生成するため、正式名称は「トークン貼り付け演算子」です。結果が有効な前処理トークンである場合にのみ有効であることに注意してください。たとえば、+ ## 3を作成することはできません+3。(ただし+ 3、もちろん、オペレーターなしで実行できます)
MM

回答:


175

## 連結のプリプロセッサ演算子です。

だからあなたが使うなら

DEFINE_STAT(foo)

コード内のどこでも、次のように置き換えられます

struct FThreadSafeStaticStat<FStat_foo> StatPtr_foo;

コードがコンパイルされる前。

これをさらに説明するために、私のブログ投稿からの別の例を次に示します。

#include <stdio.h>

#define decode(s,t,u,m,p,e,d) m ## s ## u ## t
#define begin decode(a,n,i,m,a,t,e)

int begin()
{
    printf("Stumped?\n");
}

このプログラムは正常にコンパイルおよび実行され、次の出力を生成します。

Stumped?

このコードでプリプロセッサが呼び出されると、

  • begin に置き換えられます decode(a,n,i,m,a,t,e)
  • decode(a,n,i,m,a,t,e) に置き換えられます m ## a ## i ## n
  • m ## a ## i ## n に置き換えられます main

したがって、事実上、begin()に置き換えられmain()ます。


8
##の振る舞いを学ぶためにそんなに考えるとは思っていませんでしたが、今では決して忘れないのではないでしょうか。ほんとありがと。
NicoBerrogorry 2018年

2
それをフォローするのに少し時間がかかりましたが、これは質問に対する素晴らしい答えでした。ありがとう。
n00dle
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.