3

我需要用两个不同的库编译相同的代码。一个允许对象为 const,另一个不允许。现在实施的解决方案如下所示:

#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 所说,可以将它们实例化为非常量。我改了句。

4

4 回答 4

4

您可以使用std::conditional基于编译时变量在两种类型之间进行选择:

#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

最简单的解决方案似乎是只使用非常量对象并让编译器在新接口期望的位置自动添加 const。

或者,您可以在处理器块内使用 typedef 吗?

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

你可以 typedef

// 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 回答