在C+中,有没有办法在编译时更改函数原型+;? 假设你必须编写C++、C++ 11、C++ 17等< /P>编译的代码

在C+中,有没有办法在编译时更改函数原型+;? 假设你必须编写C++、C++ 11、C++ 17等< /P>编译的代码,c++,c++11,c++14,c++17,C++,C++11,C++14,C++17,例如,这样的函数 bool Ispalindrome(const std::string &str) { // Code } 编译在所有C++实现下。但是如果你想使用旧的和新的C++17字符串视图特性,你必须处理类似的东西 #ifdef LEGACYCPP bool Ispalindrome(const std::string &str) { // Code } #elseif CPP17 bool Ispalindrome(std

例如,这样的函数

bool Ispalindrome(const std::string &str) 
{ 
   // Code 
}

编译在所有C++实现下。但是如果你想使用旧的和新的C++17字符串视图特性,你必须处理类似的东西

#ifdef LEGACYCPP
   bool Ispalindrome(const std::string &str) 
  { 
     // Code 
  }
#elseif CPP17
  bool Ispalindrome(std::string_view str) 
  { 
     // OMG Repeated Code 
  }
#endif
使用条件编译是正确的,但必须重复代码

有没有办法在编译时选择函数原型?或者其他方法来避免双重编码?(在可以应用的情况下)

谢谢

如果您可以确保函数的代码部分在每种情况下都是等效的,那么您可以为参数列表使用宏定义:

#ifdef ISCPP17
#定义PALIN_参数std::string_view str
#否则
#定义佩林参数常量std::string&str
#恩迪夫
布尔·伊斯帕林德罗姆(佩林·帕拉姆斯)
{ 
//代码
}
#未定义佩林参数
当然,这个主题有很多变体:您可以在宏定义中省略“str”部分,在签名中添加
(PALIN_PARAMS str)
。但是,使用“原样”也将允许使用不同类型的多个参数

但我不确定这类事情是否会通过
C++
清教徒的询问

另一种(可能更健壮的)方法是使用条件编译块和
使用
(或
typedef
)语句来定义参数类型:

#ifdef ISCPP17
使用cnstrg=std::string_view;//或typedef std::string_view cnstrg;
#否则
使用cnstrg=const std::string&;
#恩迪夫
布尔伊斯帕林德罗姆(CNSTRG街)
{
//代码
返回true;
}

如果是完全重复的代码,则执行以下小更改:

#ifdef CPP17
  bool Ispalindrome(std::string_view str)
#else // all versions of LEGACYCPP
  bool Ispalindrome(const std::string &str)
#endif
  { 
     // Same Code 
  }

如果函数的一小部分是版本所独有的,那么也可以在那里应用同样的技巧。

在头文件中,您需要执行以下操作

#if __cplusplus >= 201703L
   #include <string_view>
   bool Ispalindrome(std::string_view str);
#else
   #include <string>
   bool Ispalindrome(const std::string &str);
#endif
\uuuu cplusplus
在标准中指定,并在每个编译单元中预定义
201703L
表示C++17编译器,更大的值是最新的标准


假定一个实现(编译器和库)正确地声明符合C++标准。

嗯,只要函数函数中可以互换使用不同的参数类型,就可以将第一行(或仅参数列表)放进<代码> > IFIFF/…/y} NEnf/COD>内。你的代码实际为非C++17编译器编译的可能性有多大?C++与其他平台(如java、.net等)相比的优点在于,不受用户系统平台的限制,而只限于构建机器的平台。除非你有义务支持C++版本和STL在C++ 17之前的版本,然后放下你的脚,自豪地说,你不会为了拒绝使用现代编译器工具链的用户而牺牲你的项目。如果这是一个开源项目,那么如果有人要求C++11支持,请告诉他们提交一份PR。如果你为视频游戏机编写代码,很可能会有旧的编译器。你应该展示
//code
,以获得比一般提示更多的信息。我觉得你尝试得太多了。更容易获得c++11的string_视图实现并使用它进行swing。另外,出于好奇,哪个控制台不支持c++17?这种方法的一个小问题是,如果有更多这样的函数,那么每次我们都必须
#取消PALIN_参数的定义
,或者通过跟踪使用不同的宏名称。最好是取消定义,因为编译器对重新定义的警告有时可能会被忽略。@iammilind我100%同意!何时(或是否)使用此类宏的问题在很大程度上取决于此类问题发生的频率以及可能存在的变体数量。但是您使用
#undef
的观点是很好的(请参见编辑)。在
#ifdef
开始变得更安全之前,请使用
#undef
。第二种方法可能不适用于2个或更多参数,除非您
typedef
每一个参数。@iammilind实际上,第二种方法只适用于参数列表的一般形状相似的情况(并且每个“variant”arg.type都需要typedef/using)。在哪里使用
#undef
——我想这是风格的问题。当开始使用
#undef
时,可以保证清除陈旧的定义。如果您在底部使用它作为代码,那么读者不确定它以前是否仍然定义过。前者比后者具有更好的可读性。
#if __cplusplus >= 201703L
    bool Ispalindrome(std::string_view str) 
#else
    bool Ispalindrome(const std::string &str)
#endif
{ 
 // OMG no repeated code 
}