Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 优雅地重用代码,将常量添加到类实例化中_C++_Constants_C Preprocessor - Fatal编程技术网

C++ 优雅地重用代码,将常量添加到类实例化中

C++ 优雅地重用代码,将常量添加到类实例化中,c++,constants,c-preprocessor,C++,Constants,C Preprocessor,我需要用两个不同的库编译相同的代码。一个允许对象为常量,另一个不允许。现在实施的解决方案如下所示: #ifdef (OLDLIB) ClassFoo TheFoo = Bar(); #else const ClassFoo TheFoo = Bar(); #endif #ifdef OLDLIB # define LIB_CONST #else # define LIB_CONST const LIB_CONST ClassFoo TheFoo(Bar()); 这在不同

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

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

LIB_CONST ClassFoo TheFoo(Bar());
这在不同的类中被多次使用,并且会影响可读性。我想在别的地方做一下区分

我想有人会说:

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

我很确定您必须使用预处理器才能完成目标

然而,我可能会这样写:

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

LIB_CONST ClassFoo TheFoo(Bar());
这两种方法都不是非常优雅,但这样做至少意味着您只需通过预处理器而不是整个对象声明来调整对象属性。

您可以根据编译时变量在两种类型之间进行选择:

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

std::conditional<OLD, ClassFoo, const ClassFoo>::type theFoo;
                 ~~~  ~~~~~~~~  ~~~~~~~~~~~~~~
                        true        false
#ifdef OLDLIB
constexpr bool OLD=true;
#否则
constexpr bool OLD=false;
#恩迪夫
std::conditional::输入foo;
~~~  ~~~~~~~~  ~~~~~~~~~~~~~~
真假

由于C++11,最简单的解决方案似乎是只使用非常量对象,让编译器在新接口需要的地方自动添加常量

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

#ifdef (OLDLIB)
    typedef ClassFoo InstantiableFoo;
#else
    typedef const ClassFoo InstantiableFoo;
#endif
你可以输入def

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

我想知道你不喜欢的预处理器解决方案有什么特别的地方。我不明白。为什么不能将一个非
const
对象传递给一个期望
const
的函数?@Steven所有预处理器解决方案都让我感到紧张,因为我看到在使用它们的地方发生了不好的事情。我只在没有更好的方法时才使用它们,而且通常有更好的方法。谷歌搜索Stroustrup或Stutter关于预处理器的内容。