3

2 つの異なるライブラリで同じコードをコンパイルする必要があります。1 つはオブジェクトを const にすることを許可し、もう 1 つは許可しません。現在実装されているソリューションは次のようになります。

#ifdef (OLDLIB)
    ClassFoo TheFoo = Bar();
#else
    const ClassFoo TheFoo = Bar();
#endif

これは、さまざまなクラスで何度も使用され、読みやすさを妨げます。どこかで差別化したい。

私は次のように言うことができると思います:

#ifdef (OLDLIB)
#define CLASS_FOO ClassFoo
#define CLASS_BAR ClassBar
#else
#define CLASS_FOO const ClassFoo
#define CLASS_BAR const ClassBar
#endif

CLASS_FOO TheFoo = Bar();
CLASS_BAR TheBar = FooBar();

しかし、私はプリプロセッサが嫌いです。上記を行う素敵な C++ の方法はありますか? ありがとう。

更新 1:Peter Wood が言ったように、それらを非 const でインスタンス化することは可能です。文を変えました。

4

4 に答える 4

4

std::conditionalコンパイル時の変数に基づいて、次の 2 つのタイプから選択するために使用できます。

#ifdef OLDLIB
constexpr bool OLD = true;
#else
constexpr bool OLD = false;
#endif

std::conditional<OLD, ClassFoo, const ClassFoo>::type theFoo;
                 ~~~  ~~~~~~~~  ~~~~~~~~~~~~~~
                        true        false

C++11以降

于 2013-05-28T14:25:03.160 に答える
3

目標を達成するためにプリプロセッサにこだわっていると確信しています。

しかし、私はおそらく次のように書くでしょう:

#ifdef OLDLIB
#  define LIB_CONST
#else
#  define LIB_CONST const

LIB_CONST ClassFoo TheFoo(Bar());

どちらの方法も非常に洗練された方法ではありませんが、このようにすることは、少なくともオブジェクト宣言全体ではなく、プリプロセッサを介してオブジェクト属性を微調整しているだけであることを意味します。

于 2013-05-28T14:23:16.870 に答える
1

タイプ定義できます

// oldlib.h
typedef ClassFoo Foo;
typedef ClassBar Bar;

// newlib.h
typedef const ClassFoo Foo;
typedef const ClassBar Bar;


// the library's user
#include "oldlib.h"       // or include "which_lib.h" that includes
                          // one of oldlib.h newlib.h
#include "your_library_that_uses_the_typedefs.h"

Foo TheFoo = Bar();
Bar TheBar = FooBar();

ライブラリのクラスとグローバル関数をパラメータ化できます

// library.h
template <class Foo>
class SomeClass { }

template <class Foo>
Foo makeFoo() { }

// library_user.cpp

#include "library.h"
SomeClass<const ClassFoo> sc;
sc.method();
const ClassFoo f = makeFoo();

外部ライブラリ内の Foo 型を非表示にすることもできます

// external_library.h
class ExternalLibrary {
     typedef const Foo foo_type;
};

ExternalLibrary::foo_type& foo_identity(const ExternalLibrary::foo_type &v) { return v; }

// your_library.h

ExternalLibrary::foo_type makeFoo() { }

foo_identity(f1);
于 2013-05-28T14:59:34.027 に答える
1

最も簡単な解決策は、const 以外のオブジェクトを使用し、新しいインターフェイスが期待する場所にコンパイラが const を自動的に追加するようにすることです。

または、proprocessor ブロック内で typedef を使用できますか?

#ifdef (OLDLIB)
    typedef ClassFoo InstantiableFoo;
#else
    typedef const ClassFoo InstantiableFoo;
#endif
于 2013-05-28T14:47:05.010 に答える