假设您必须编写应在C ++,C ++ 11,C ++ 17等环境下编译的代码。
例如这样的功能。
bool Ispalindrome(const std::string &str)
{
// Code
}
可以在所有C ++实现中进行编译。但是,如果您想使用新旧的C ++ 17 string_view功能,则需要处理类似
#ifdef LEGACYCPP
bool Ispalindrome(const std::string &str)
{
// Code
}
#elseif CPP17
bool Ispalindrome(std::string_view str)
{
// OMG Repeated Code
}
#endif
使用条件编译是正确的,但是必须重复代码。
在编译时是否可以选择函数原型?还是其他避免双重编码的方式? (在可以应用的情况下)
谢谢
答案 0 :(得分:3)
如果可以确保在每种情况下函数的代码段都等同于 ,则可以对参数列表使用宏定义:>
#ifdef ISCPP17
#define PALIN_PARAMS std::string_view str
#else
#define PALIN_PARAMS const std::string& str
#endif
bool Ispalindrome(PALIN_PARAMS)
{
// Code
}
#undef PALIN_PARAMS
关于此主题,当然有很多变体:您可以在宏定义中省略“ str”部分,并在签名中使用(PALIN_PARAMS str)
。但是,使用“按原样”还将允许使用不同类型的多个参数。
但是我不确定这种事情是否会通过C++
清教徒的宗教裁判所。
另一种(可能更健壮)的方法是将条件编译块与using
(或typedef
)语句一起使用以定义参数类型:
#ifdef ISCPP17
using cnststrg = std::string_view; // Or typedef std::string_view cnststrg;
#else
using cnststrg = const std::string&;
#endif
bool Ispalindrome(cnststrg str)
{
// Code
return true;
}
答案 1 :(得分:3)
在头文件中,您需要执行类似的操作
#if __cplusplus >= 201703L
#include <string_view>
bool Ispalindrome(std::string_view str);
#else
#include <string>
bool Ispalindrome(const std::string &str);
#endif
在您的定义中,您需要先添加标题,然后执行
#if __cplusplus >= 201703L
bool Ispalindrome(std::string_view str)
#else
bool Ispalindrome(const std::string &str)
#endif
{
// OMG no repeated code
}
__cplusplus
在标准中指定,并且在每个编译单元中都已预定义。 201703L
表示C ++ 17编译器,值越大,表示最新的标准。
这假设一个实现(编译器和库)正确声明符合各自的C ++标准。
答案 2 :(得分:2)
然后提供完全重复的代码,请执行以下较小更改:
#ifdef CPP17
bool Ispalindrome(std::string_view str)
#else // all versions of LEGACYCPP
bool Ispalindrome(const std::string &str)
#endif
{
// Same Code
}
如果功能的一小部分是版本独有的,则也可以在上面应用相同的技巧。