質問

C プリプロセッサは当然の恐れによって社会から葬りのC++です。内張り機能、consts、ステークホルダーに対して通常より安全で優れた代替品 #define.

以下のマクロ:

#define SUCCEEDED(hr) ((HRESULT)(hr) >= 0)  

ックするだけで簡単に登録出来るの型安全な:

inline bool succeeded(int hr) { return hr >= 0; }

がマクロな場合はご記入下さい使用だけのためのマクロま できない なプリプロセッサー.

入れてください各利用の場合は、別の回答ができる投票と、そしてご存知の方はどのように実現する一つの答えなのpreprosessor点はどのように答える。

役に立ちましたか?

解決

としてラッパーのためのデバッグ機能は、自動的に通う __FILE__, __LINE__, 等:

#ifdef ( DEBUG )
#define M_DebugLog( msg )  std::cout << __FILE__ << ":" << __LINE__ << ": " << msg
#else
#define M_DebugLog( msg )
#endif

他のヒント

方法についての完全compilableコードマクロがコードである。このように定義することができ、foreachのマクロ:

#define foreach(list, index) for(index = 0; index < list.size(); index++)

持っていないと見ることができる。

foreach(cookies, i)
    printf("Cookie: %s", cookies[i]);

以来、C++11、折の 範囲に基づくループ.

ヘッダファイルの警備員を必要とマクロです。

その他の地域 を必要とし マクロ?います。

その他の状況から利益を得ているマクロ?ああ!!!

一つの場所を使っていマクロが非常に繰り返します。例えば、包C++のコードで使用されるその他のインタフェース(.NET、COM、Python、など...)ながらプレーする必要がありまャ異なる種類の例外をスローしました。こちらかということですかね:

#define HANDLE_EXCEPTIONS \
catch (::mylib::exception& e) { \
    throw gcnew MyDotNetLib::Exception(e); \
} \
catch (::std::exception& e) { \
    throw gcnew MyDotNetLib::Exception(e, __LINE__, __FILE__); \
} \
catch (...) { \
    throw gcnew MyDotNetLib::UnknownException(__LINE__, __FILE__); \
}

していますの一部として購入するとき、捕べてのラッパー機能。なタイプのフチブロック毎のうち、タイプ:

void Foo()
{
    try {
        ::mylib::Foo()
    }
    HANDLE_EXCEPTIONS
}

これもメンテナンス性も向上します。だって新しい例外の型がなんでもかんでも規則まみっ追加する必要があります。

ありその他の有用な事例も多くが含まれますが、この限りでは、 __FILE____LINE__ プリプロセッサマクロです。

とにかく、マクロは非常に有用できます。マクロな悪--その ご用 ですよね

主:

  1. などの警備員
  2. 条件コンパイル
  3. 報告書(所定のマクロのように __LINE____FILE__)
  4. (な)複製繰り返しコードパターン
  5. お競合他社のコードです。

内部条件コンパイル、課題を克服の違いをコンパイラでコンパイル:

#ifdef ARE_WE_ON_WIN32
#define close(parm1)            _close (parm1)
#define rmdir(parm1)            _rmdir (parm1)
#define mkdir(parm1, parm2)     _mkdir (parm1)
#define access(parm1, parm2)    _access(parm1, parm2)
#define create(parm1, parm2)    _creat (parm1, parm2)
#define unlink(parm1)           _unlink(parm1)
#endif

がしたい文字列の表現には assert (#x 回を重ねるごとに価値の x 文字列).

#define ASSERT_THROW(condition) \
if (!(condition)) \
     throw std::exception(#condition " is false");

文字列定数のものはより良い定義としてマクロにすることができるのでいたりの文字列リテラルによる const char *.

例えば文字列リテラルできる 簡単に連結され.

#define BASE_HKEY "Software\\Microsoft\\Internet Explorer\\"
// Now we can concat with other literals
RegOpenKey(HKEY_CURRENT_USER, BASE_HKEY "Settings", &settings);
RegOpenKey(HKEY_CURRENT_USER, BASE_HKEY "TypedURLs", &URLs);

の場合 const char * 使用された後に何らかの文字列のクラスに合わせて最適化されている連結実行時:

const char* BaseHkey = "Software\\Microsoft\\Internet Explorer\\";
RegOpenKey(HKEY_CURRENT_USER, (string(BaseHkey) + "Settings").c_str(), &settings);
RegOpenKey(HKEY_CURRENT_USER, (string(BaseHkey) + "TypedURLs").c_str(), &URLs);

変更する場合がございますので、プログラムフローreturn, breakcontinue このコード機能の動作とは違ったコードで実際にinlinedの機能です。

#define ASSERT_RETURN(condition, ret_val) \
if (!(condition)) { \
    assert(false && #condition); \
    return ret_val; }

// should really be in a do { } while(false) but that's another discussion.

を明らかを含むガード

#ifndef MYHEADER_H
#define MYHEADER_H

...

#endif

できませんを行う短絡の関数呼び出しの引数を使用し通常の機能ます。例えば:

#define andm(a, b) (a) && (b)

bool andf(bool a, bool b) { return a && b; }

andm(x, y) // short circuits the operator so if x is false, y would not be evaluated
andf(x, y) // y will always be evaluated

をしようしを無視するかのようなヘッダーガードです。

時には生成してくださいコードをコピー/貼り付けるprecompiler:

#define RAISE_ERROR_STL(p_strMessage)                                          \
do                                                                             \
{                                                                              \
   try                                                                         \
   {                                                                           \
      std::tstringstream strBuffer ;                                           \
      strBuffer << p_strMessage ;                                              \
      strMessage = strBuffer.str() ;                                           \
      raiseSomeAlert(__FILE__, __FUNCSIG__, __LINE__, strBuffer.str().c_str()) \
   }                                                                           \
   catch(...){}                                                                \
   {                                                                           \
   }                                                                           \
}                                                                              \
while(false)

ることができるコードです:

RAISE_ERROR_STL("Hello... The following values " << i << " and " << j << " are wrong") ;

を生成することが可能でメッセージのように:

Error Raised:
====================================
File : MyFile.cpp, line 225
Function : MyFunction(int, double)
Message : "Hello... The following values 23 and 12 are wrong"

注意混合テンプレートとマクロでも良い結果に結びつ自動生成の価値を並べてその変数名)

その他、必要なものは、__FILE__、__ライン__一部のコードをデバッグ情報です。以下はクラシックのためのVisual C++:

#define WRNG_PRIVATE_STR2(z) #z
#define WRNG_PRIVATE_STR1(x) WRNG_PRIVATE_STR2(x)
#define WRNG __FILE__ "("WRNG_PRIVATE_STR1(__LINE__)") : ------------ : "

として以下のコード:

#pragma message(WRNG "Hello World")

生成することができなどのメッセージ:

C:\my_project\my_cpp_file.cpp (225) : ------------ Hello World

その他、必要なコードを生成します。用の#、##連結業者のように生成setterか、セッター物件(これはかなり限られた場合を通じて).

その他の時間は、生まれのコードなコンパイルの場合より使用する機能には、

#define MY_TRY      try{
#define MY_CATCH    } catch(...) {
#define MY_END_TRY  }

使用できるとして

MY_TRY
   doSomethingDangerous() ;
MY_CATCH
   tryToRecoverEvenWithoutMeaningfullInfo() ;
   damnThoseMacros() ;
MY_END_TRY

(まだ見ただけでこのようなコードを正しく使用 一度)

に最大限、有名な boost::foreach !!!

#include <string>
#include <iostream>
#include <boost/foreach.hpp>

int main()
{
    std::string hello( "Hello, world!" );

    BOOST_FOREACH( char ch, hello )
    {
        std::cout << ch;
    }

    return 0;
}

(注:コードのコピー/貼り付けから、ブのホームページ)

である(厚)のほうがはる std::for_each.

なので、マクロは常に有用での通常のコンパイラ。もっとも時間を見つ、効果的に残りのCコードな翻訳の適切なC++.

単体テストの枠組みのためのC++のように UnitTest++ ほとんど中心にプリプロセッサマクロです。数ラインの単体テストコード展開層を選んだの楽しみですべてのタイプになります。ないようなものUnitTest++でのプリプロセッサージがわからないん効率的に書単位試験のためのC++.

恐れのCプリプロセッサのような恐れの白熱電球かた蛍光灯のありが可能であるのに{電気|プログラマ時間}効率が悪い。ありきり焼失します。ができることを仕事場を適切に取り扱います。

きプログラム組み込みシステムCする場合がありますが、唯一のオプションで離れ形式のアセンブル.後のプログラミングデスクトップ、C++で、そのへの切り替え、組み込み目標付きの停止を気に"inelegancies"になったのは、何よりも、多くの素C機能(マクロ)かそうとしていることを最高の安全な利用の切り替えができる者が特徴です。

アレクサンダー Stepanov という:

た時にプログラムをC++すべきではない恥ずかしそのC遺産で作成されている 全使用していただいて結構です。唯一の問題とC++によるものだけが問題とCが生じると っていない一貫した自分の論理です。

を使用していまし __FILE____LINE__ マクロのための診断目的での情報の豊かな例外を投げ、獲、伐採、自動ログファイルのスキャナーに当社のQAインフラです。

例えば、マクロを投げ OUR_OWN_THROW 使用することがあ例外タイプは、コンストラクタのパラメータが例外を含むテキストでの説明を書き込む。このように:

OUR_OWN_THROW(InvalidOperationException, (L"Uninitialized foo!"));

このマクロはもちろんの InvalidOperationException 例外を説明としてのコンストラクタのパラメータでもメッセージを書き込むログファイルを構成するファイル名と行数のスローが発生し、そのテキストでの説明を書き込む。の例外がスローされませんidがログに出力されます。場合の例外では獲れかのコードで目印になるなどのログファイルを示される特定の例外に関して取り扱うことになるので行ってはならないのが原因のクラッシュがログインします。独自のレンダリングメカニズムの例外を拾い上げられる当社の自動QAインフラです。

コードを繰り返す.

している ブ図書館のプリプロセッサ, では、一種のメタmeta-プログラミングトピックス->動きを例に取り上げたいと思います。

一部の非常に高度で有用なものでも用プリプロセッサ(マクロ)、まうことができないかもしれないいのc++言語を構築します"などテンプレート。

例:

不思議な光景に出くわの両方のC識別子の文字列

で簡単に変数のenum型を文字列としてC

ブプリプロセッサMetaprogramming

ま使用にマクロで定義情報を一つの場所で利用でさまざまな異なる部品のコードです。でわずかにド)

例えば、"field_list.h:

/*
 * List of fields, names and values.
 */
FIELD(EXAMPLE1, "first example", 10)
FIELD(EXAMPLE2, "second example", 96)
FIELD(ANOTHER, "more stuff", 32)
...
#undef FIELD

そのための公共の列挙型を用いて定義することができますか軒の名:

#define FIELD(name, desc, value) FIELD_ ## name,

typedef field_ {

#include "field_list.h"

    FIELD_MAX

} field_en;

および民間のinit関数の全ての分野での移植に使用されたテーブルのデータ

#define FIELD(name, desc, value) \
    table[FIELD_ ## name].desc = desc; \
    table[FIELD_ ## name].value = value;

#include "field_list.h"

共通の使用を検出するためのコンパイル環境において、クロスプラットフォーム開発に書き込みを一つのセットコードのためのlinux、たとえば、他のwindowsない場合のクロスプラットフォーム図書館がすでに存在するお客様の目的.

なので、荒れたとえば、クロスプラットフォームミューテックスできる

void lock()
{
    #ifdef WIN32
    EnterCriticalSection(...)
    #endif
    #ifdef POSIX
    pthread_mutex_lock(...)
    #endif
}

のための機能も有したいときに明示的に無視するタイプ。などの多くの例では、上下にいることを主張する.もちろん、多くのC/C++の機能での撮影ができ自分の足ですが、言語のツールやきを決定しなければならない。

のようなもの

void debugAssert(bool val, const char* file, int lineNumber);
#define assert(x) debugAssert(x,__FILE__,__LINE__);

できるだけとい

assert(n == true);

のソースファイル名と行数の問題を印刷へのログインである場合は、nはfalseです。

ご利用の場合は通常の関数呼び出しなど

void assert(bool val);

の代わりにマクロございますのでご注意下さいでは主張機能のライン番印刷済みのログインには、将来的にご検討されている。

#define ARRAY_SIZE(arr) (sizeof arr / sizeof arr[0])

とは異なり、'preferred'テンプレートの解説、現在のスレッドで無い場合、お名前をお書き添えて一定の表現

char src[23];
int dest[ARRAY_SIZE(src)];

利用できる#を定義するデバッグおよび単体テストシナリオ.例えば、特にログインするメモリ機能をmemlog_preinclude.h:

#define malloc memlog_malloc
#define calloc memlog calloc
#define free memlog_free

コンパイルすを使用したコード:

gcc -Imemlog_preinclude.h ...

は、リンクをおmemlog.o最終イメージです。なお、現在の制御mallocなど、おそらくログインの目的は、再配分の故障のためのユニット。

Iマクロを使用して簡単に定義例外:

DEF_EXCEPTION(RessourceNotFound, "Ressource not found")

がDEF_EXCEPTIONは

#define DEF_EXCEPTION(A, B) class A : public exception\
  {\
  public:\
    virtual const char* what() const throw()\
    {\
      return B;\
    };\
  }\

コンパイラでコンパイルでお客様の個人情報の更新を要求へのインライン.

マクロは常にしています。

何かを見たいのに有する#defineデバッグ用デバッグトレース--き1つのデバッグなどにも休業での開発サイクル)をoffの場合です。

きの判断でコンパイル時間のコンパイラ/OSやハードウェアが特定の行動です。

でお楽しみいただけますよう、インターフェースComppiler/OSやハードウェアが特定の特徴です。

#if defined(MY_OS1) && defined(MY_HARDWARE1)
#define   MY_ACTION(a,b,c)      doSothing_OS1HW1(a,b,c);}
#elif define(MY_OS1) && defined(MY_HARDWARE2)
#define   MY_ACTION(a,b,c)      doSomthing_OS1HW2(a,b,c);}
#elif define(MY_SUPER_OS)
          /* On this hardware it is a null operation */
#define   MY_ACTION(a,b,c)
#else
#error  "PLEASE DEFINE MY_ACTION() for this Compiler/OS/HArdware configuration"
#endif

前回の私の仕事では、仕事を行っていたウイルスを読み取ってくれます。くもりやすいデバッグ、多かったのでログインこだわったのが、需要が高いアプリなどの費用の関数呼び出しはあまりにもかわいそうだと思う。そこで、私たこの小さなマクロもついてのデバッグログをリリース版では、お客様となく、当サイトのコストの関数呼び出しがチェックのデバッグフラグをともなくログインいた場合や、有効になロギングの...マクロのた以下のように定義して計算します:

#define dbgmsg(_FORMAT, ...)  if((debugmsg_flag  & 0x00000001) || (debugmsg_flag & 0x80000000))     { log_dbgmsg(_FORMAT, __VA_ARGS__);  }

このVA_ARGSのログ機能は、このた場合、マクロのようです。

その前に使ってのマクロの高いセキュリティの申請が必要なく、ユーザーとなって、正しいアクセスで教えフラグも必要です。

マクロ(s)に定義されている。

#define SECURITY_CHECK(lRequiredSecRoles) if(!DoSecurityCheck(lRequiredSecRoles, #lRequiredSecRoles, true)) return
#define SECURITY_CHECK_QUIET(lRequiredSecRoles) (DoSecurityCheck(lRequiredSecRoles, #lRequiredSecRoles, false))

しただけでふりかけ、チェックすべてのUIなので教えてくれるでしょた役割分担を可能にするために、できませんでした。理由は二つのうち戻り値の型関数が値を返すことからvoid関数のワークショップを行いました。

SECURITY_CHECK(ROLE_BUSINESS_INFORMATION_STEWARD | ROLE_WORKER_ADMINISTRATOR);

LRESULT CAddPerson1::OnWizardNext() 
{
   if(m_Role.GetItemData(m_Role.GetCurSel()) == parent->ROLE_EMPLOYEE) {
      SECURITY_CHECK(ROLE_WORKER_ADMINISTRATOR | ROLE_BUSINESS_INFORMATION_STEWARD ) -1;
   } else if(m_Role.GetItemData(m_Role.GetCurSel()) == parent->ROLE_CONTINGENT) {
      SECURITY_CHECK(ROLE_CONTINGENT_WORKER_ADMINISTRATOR | ROLE_BUSINESS_INFORMATION_STEWARD | ROLE_WORKER_ADMINISTRATOR) -1;
   }
...

思うに使用しましたし、いかに助けていただきましたとのテンプレート...以上、どうしたらいいでしょうかをしないようにしていない限り、本当に必要です。

なforeachマクロです。T:タイプcコンテナi:反復子

#define foreach(T, c, i) for(T::iterator i=(c).begin(); i!=(c).end(); ++i)
#define foreach_const(T, c, i) for(T::const_iterator i=(c).begin(); i!=(c).end(); ++i)

使用量(コンセプトを示し、実質):

void MultiplyEveryElementInList(std::list<int>& ints, int mul)
{
    foreach(std::list<int>, ints, i)
        (*i) *= mul;
}

int GetSumOfList(const std::list<int>& ints)
{
    int ret = 0;
    foreach_const(std::list<int>, ints, i)
        ret += *i;
    return ret;
}

より良い実装が可能Google "BOOST_FOREACH"

良い記事をご用意 条件の愛:FOREACH Redux (エリック-Niebler) http://www.artima.com/cppsource/foreach.html

(粉を山にして真ん中をgreates使用量のマクロはプラットフォームを開発。考えの場合の型の不一致とマクロ利用することさえ可能ですの異なるヘッダファイル--のように:--WIN_TYPES.H

typedef ...some struct

--POSIX_TYPES.h

typedef ...some another struct

--プログラム。h

#ifdef WIN32
#define TYPES_H "WINTYPES.H"
#else 
#define TYPES_H "POSIX_TYPES.H"
#endif

#include TYPES_H

も読み取りを実施する他に方法はないのにと思います。

そうVA_ARGSていて間接的にこれまで:

書くときの汎用C++03コードし、必要な数の可変数(汎用)パラメータをお使いいただけますのでマクロの代わりにテンプレートを作成します。

#define CALL_RETURN_WRAPPER(FnType, FName, ...)          \
  if( FnType theFunction = get_op_from_name(FName) ) {   \
    return theFunction(__VA_ARGS__);                     \
  } else {                                               \
    throw invalid_function_name(FName);                  \
  }                                                      \
/**/

注意: 一般的には、氏名の確認/throwが組み込まれ、仮説 get_op_from_name 機能です。これはほんの一例になります。がその他の汎用コードのVA_ARGSます。

またvariadicテンプレートのC++11まで解決できるこの"適切に"とのテンプレートを作成します。

このコツは巧みな使用のプリプロセッサできないエミュレーション機能:

#define COMMENT COMMENT_SLASH(/)
#define COMMENT_SLASH(s) /##s

#if defined _DEBUG
#define DEBUG_ONLY
#else
#define DEBUG_ONLY COMMENT
#endif

そして使用できるようになります:

cout <<"Hello, World!" <<endl;
DEBUG_ONLY cout <<"This is outputed only in debug mode" <<endl;

を定義することもできるRELEASE_ONLYをクリックします。

ができ #define 定数のコンパイラのコマンドラインを使用 -D または /D オプションです。これは通常のクロス集計を同じソフトウェアのためのマルチプラットフォームができる実行制御にどの定数が定義されたそれぞれのプラットフォーム.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top