Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.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++ 有没有办法阻止开发人员使用std::min、std::max?_C++ - Fatal编程技术网

C++ 有没有办法阻止开发人员使用std::min、std::max?

C++ 有没有办法阻止开发人员使用std::min、std::max?,c++,C++,我们有一个算法库,对可能是NaN的数字执行大量的std::min/std::max操作。考虑到这篇文章,我们意识到这显然是不安全的 有没有办法阻止开发人员使用std::min/std::max 我们的代码是用VS2015和g++编译的。我们的所有源文件都包含一个通用头文件(通过VS2015的/FI选项和g++的-include)。是否有任何代码/pragma可以放在这里,使任何cpp文件使用std::min或std::max编译失败 顺便说一句,像使用此函数的STL头这样的遗留代码不应该受到影响

我们有一个算法库,对可能是NaN的数字执行大量的
std::min
/
std::max
操作。考虑到这篇文章,我们意识到这显然是不安全的

有没有办法阻止开发人员使用
std::min
/
std::max

我们的代码是用VS2015和g++编译的。我们的所有源文件都包含一个通用头文件(通过VS2015的
/FI
选项和g++的
-include
)。是否有任何代码/pragma可以放在这里,使任何cpp文件使用
std::min
std::max
编译失败

顺便说一句,像使用此函数的STL头这样的遗留代码不应该受到影响。只有我们编写的代码应该受到影响。

没有可移植的方法来做到这一点,因为除了几个例外,您不允许在
std
中更改任何内容

然而,一个解决办法是

#定义max foo

在包含任何代码之前。然后
std::max
max
都会出现编译时故障


但实际上,如果我是你,我会习惯你平台上的
std::max
std::min
行为。如果他们没有按照标准要求去做,那么就向编译器供应商提交一份bug报告。

我认为让标准库函数不可用不是正确的方法。首先,NaN是浮点值工作原理的一个基本方面。您需要禁用所有其他功能,例如,
sort()
下限()
,等等。此外,程序员因创造性而获得报酬,我怀疑任何想要使用
std::max()
的程序员都会犹豫使用
a
如果std::max(a,b)不起作用

此外,您显然不希望对没有NaN的类型(例如整数或字符串)禁用
std::max()
std::min()
。所以,你需要一个有点控制的方法

没有可移植的方法来禁用命名空间
std
中的任何标准库算法。您可以通过提供适当的
delete
d重载来定位这些算法的使用,例如:

namespace std {
    float       max(float, float) = delete;             // **NOT** portable
    double      max(double, double) = delete;           // **NOT** portable
    long double max(long double, long double) = delete; // **NOT** portable
    // likewise and also not portable for min
}

这里我要讲一点哲学,少讲代码。但我认为最好的方法是教育这些开发人员,并解释为什么他们不应该以特定的方式编写代码。如果你能给他们一个很好的解释,那么他们不仅会停止使用你不希望他们使用的函数。他们将能够将信息传播给团队中的其他开发人员


我相信强迫他们只会让他们想出解决办法。

您不赞成使用std::min std::max。您可以通过使用grep进行搜索来找到实例。或者,您可以随意处理标题本身,以中断std::min,std::max。或者您可以尝试为预处理器定义min/max或std::min,std::max。后者由于C++命名空间有点狡猾,如果您定义了STD::Max/min,则不使用命名空间STD,如果定义MI/MAX,也会获取这些标识符的其他用法。
#pragma GCC poison min max atoi /* etc ... */
或者,如果项目有一个每个人都包含的标准标题,如“mylibrary.lib”,则在其中断开std::min/max


当然,当传递NaN时,函数应该返回NaN。但是写它们的自然方式总是会触发错误。

因为修改
std
是不允许的,下面是UB,但在您的情况下可能会起作用。 将函数标记为已弃用:

自c++14以来,不推荐使用的属性:

namespace std
{
    template <typename T>
    [[deprecated("To avoid to use Nan")]] constexpr const T& (min(const T&, const T&));
    template <typename T>
    [[deprecated("To avoid to use Nan")]] constexpr const T& (max(const T&, const T&));
}
名称空间std
{
模板
[[已弃用(“避免使用Nan”)]]constexpr const T&(min(const T&,const T&));
模板
[[已弃用(“避免使用Nan”)]]constexpr const T&(max(const T&,const T&));
}

之前

#ifdef __GNUC__
# define DEPRECATED(func) func __attribute__ ((deprecated))
#elif defined(_MSC_VER)
# define DEPRECATED(func) __declspec(deprecated) func
#else
# pragma message("WARNING: You need to implement DEPRECATED for this compiler")
# define DEPRECATED(func) func
#endif

namespace std
{
    template <typename T> constexpr const T& DEPRECATED(min(const T&, const T&));
    template <typename T> constexpr const T& DEPRECATED(max(const T&, const T&));

}
\ifdef\uu GNUC__
#定义不推荐的(func)func ____((不推荐))
#elif已定义(\u MSC\u VER)
#定义已弃用(func)\定义已弃用(func)
#否则
#pragma消息(“警告:您需要为此编译器实现弃用”)
#定义不推荐使用的(func)func
#恩迪夫
名称空间标准
{
模板constexpr const T&已弃用(最小值(const T&,const T&));
模板constexpr const T&已弃用(最大值(const T&,const T&));
}

我不打算准确地回答你的问题,但你可以教育你的同事,确保你一直使用总订单比较器,而不是原始的
运算符std::min
std::max
无论何时使用依赖于给定订单的函数。/p pSuch a比较器是为标准化而提出的(以及部分和弱阶比较器),可能以C++20为目标。与此同时,C标准委员会已经在这方面工作了相当长的一段时间,显然是针对未来的C2x(应该是~C23),它用许多新函数更新了codemath.h/code头,以实现最近的版本。在新函数中,有codetotalorder/code(第14.8节),它根据IEEE codetotalorder/code:/p比较浮点数 块引用 ptotalOrder(emx/em,emy/em)对emx/em和emy/em格式的规范成员施加总排序:/p ol li如果emx/emy,则totalOrder(x,y)为false
  • 如果x=y
  • totalOrder(-0,+0)为真
  • totalOrder(+0,-0)为false
  • 如果x和y表示相同的浮点基准:
    • 如果x和y有负号,则totalOrder(x,y)为真当且仅当x的指数为≥ y的指数
    • 否则totalOrder(x,y)为真当且仅当x的指数为≤ y的指数
  • 如果x和y是无序的数字
    error: attempt to use poisoned "min"
    
    #define strrchr rindex
    #pragma GCC poison rindex
    strrchr(some_string, 'h');