对关键容器的键类型(例如std :: map)的比较器的要求是它对键类型的元素施加严格的弱顺序.
对于给定的比较器,comp(x, y)
我们定义equiv(x, y) = !comp(x, y) && !comp(y, x)
.严格弱势秩序
的要求comp(x, y)
是
!comp(x, x)
适合所有人x
)comp(a, b)
和comp(b, c)
再comp(a, c)
).equiv(a, b)
和equiv(b, c)
然后equiv(a, c)
)std::less<float>
(默认比较器)使用operator<
,因为没有创建严格的弱顺序NaN
.由于x < NaN
和NaN < x
是全是假的x
,NaN
就相当于这个比较下的所有花车,这打破条件#3:equiv(1.0, NaN)
和equiv(NaN, 2.0)
,但不会equiv(1.0, 2.0)
.对于除NaN之外的IEEE浮点数,它是一个严格的弱顺序(其中每个数字都有自己的等价类,除了0
和-0
).
这是否意味着C++标准不允许使用IEEE浮点数(和(长)双精度数)作为关联容器中的键类型,因为上述问题,即使我确保NaN永远不会插入到容器中?我不太确定 …
我写了下面的c++
程序CodeBlocks
,结果是9183.我再次写入Eclipse
和运行后,它返回9220.两者都使用MinGW
.正确的结果是9183.这段代码出了什么问题?谢谢.源代码:
#include <iostream>
#include <set>
#include <cmath>
int main()
{
using namespace std;
set<double> set_1;
for(int a = 2; a <= 100; a++)
{
for(int b = 2; b <= 100; b++)
{
set_1.insert(pow(double(a), b));
}
}
cout << set_1.size();
return 0;
}
Run Code Online (Sandbox Code Playgroud) 以下课程是否打破了严格的弱排序(与常规相比std::less
(因此忽略边缘情况值,例如 Nan))
struct LessWithEpsilon
{
static constexpr double epsilon = some_value;
bool operator() (double lhs, double rhs) const
{
return lhs + epsilon < rhs;
}
};
LessWithEpsilon lessEps{};
Run Code Online (Sandbox Code Playgroud) 我的程序中有一个std :: map,它存储了一对值.我希望地图中的键是唯一的 - 这是std :: map类的预期行为.但是当我将对插入其中时,会重复一些键.我该如何解决这个问题?
我的代码如下:
map<float,vector<float> *> inpDataMap;
inpDataMap.clear();
for(int i = 0; i < input.getNum(); i++)
{
float xVal = input[i][0];
float yVal = input[i][1];
if(inpDataMap.count(xVal) > 0)
{
myfile << i << " repeated xval: " << xVal << " : " << yVal << endl;
inpDataMap[xVal]->push_back(yVal);
myfile << "repeated value pushed" << endl;
}
else
{
vector<float> *inVec = new vector<float>;
inVec->push_back(yVal);
inpDataMap[xVal] = inVec;
myfile << i << " not repeated:" << xVal …
Run Code Online (Sandbox Code Playgroud) 可能重复:
std:map中的浮点键
我知道有些情况下你想提供一个特殊的功能来进行双打比较.这种情况可能包括您进行算术运算的次数,因为您在浮点运算中得到了舍入.
但有时使用<或>来比较双打是否安全?
假设我有一次计算的双精度列表,我需要将其排序或用作地图中的一个键(即.std :: map),并保证之后没有任何额外的算术运算.
如果我使用迭代器遍历集合,我可以保证我的排序顺序是否正确?
我想我可以通过这种方式获得更多性能.
我如何在 boost 精神解析器中添加警告。
编辑: ...可以报告位置问题
例如,如果我有一个整数解析器:
('0' >> oct)
| int_
Run Code Online (Sandbox Code Playgroud)
我希望能够做这样的事情:
('0' >> oct)
| "-0" --> trigger warning("negative octal values are not supported, it will be interpreted as negative decimal value and the leading 0 will be ignored")
| int_
Run Code Online (Sandbox Code Playgroud) 要求:
- 容器根据数字比较键进行排序(例如std :: map)
- 根据浮动容差检查密钥是否存在(例如map.find()并使用自定义比较器)
- 而且棘手的是:比较器使用的浮动公差可以由用户在运行时更改!
前两个可以使用带有自定义比较器的地图完成:
struct floatCompare : public std::binary_function<float,float,bool>
{
bool operator()( const float &left, const float &right ) const
{
return (fabs(left - right) > 1e-3) && (left < right);
}
};
typedef std::map< float, float, floatCompare > floatMap;
Run Code Online (Sandbox Code Playgroud)
使用此实现,floatMap.find(15.0001)将在地图中找到15.0.
但是,假设用户不希望浮动容差为1e-3.使比较器函数在运行时使用可变容差的最简单方法是什么?我不介意每次更新epsilon时都会根据新的比较器重新创建和重新排序地图.