优雅地重用将const添加到类实例化中的代码

Elegantly reuse code adding const to a class instantiation

本文关键字:实例化 代码 添加 const      更新时间:2023-10-16

我需要用两个不同的库编译相同的代码。一个允许对象为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所说,可以将它们实例化为非const。我改了句

您可以使用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

我很确定你是在用预处理器来完成你的目标。

但是,我可能会这样写:

#ifdef OLDLIB
#  define LIB_CONST
#else
#  define LIB_CONST const
LIB_CONST ClassFoo TheFoo(Bar());

这两种方式都不是很优雅,但这样做至少意味着你只是通过预处理器调整对象属性,而不是整个对象声明。

最简单的解决方案似乎是使用非const对象,并让编译器在新接口需要它的地方自动添加const。

或者你可以在proprocessor块中使用typedef吗?

#ifdef (OLDLIB)
    typedef ClassFoo InstantiableFoo;
#else
    typedef const ClassFoo InstantiableFoo;
#endif

可以输入pedef

// 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);