我编写了一些(正在工作的)测试代码,但我不明白为什么在test1函数中,我只能传递一个int* const作为参数,而在test2函数中,我可以传递一个const int*。如果我将一个const int*传递给test1,就会得到一个丢弃限定符错误。
在我的研究中,我发现std::find和set::find都有一个const版本,所以我不明白它们为什么表现不同。我也尝试使用boost::container::flat_set而不是std::set,并得到了相同的结果。谁能解释一下吗?
class myClass
{
public:
myClass() {};
~myClass() {};
void add(int* ref)
{
this->_ref.insert(ref);
};
bool test1(int* const ref) const
{
return ( this->_ref.find(ref) != this->_ref.end() );
}
inline
bool test2(const int* ref) const
{
return ( std::find(this->_ref.begin(), this->_ref.end(), ref) != this->_ref.end() );
}
std::set<int*> _ref;
};
int main()
{
myClass test;
test.add(new int(18));
test.add(new int(35));
test.add(new int(78));
test.add(new int(156));
std::cout<<test.test1(0)<<std::endl;
std::cout<<test.test1(*test._ref.begin())<<std::endl;
std::cout<<test.test2(0)<<std::endl;
std::cout<<test.test2(*test._ref.begin())<<std::endl;
return 0;
}发布于 2015-09-17 08:49:05
容器std::set<int*>只有同构查找,所以您只能通过将它们与相同类型的值( find、count、erase )进行比较来搜索密钥。当然,const int*类型的值与int*没有相同的类型,因此您的test2代码尝试将前者转换为后者,这是不允许的转换。
容器只能以类似的方式使用这一事实从一开始就是C++的一个缺点,更严重的不需要转换的例子是当您有一个带有std::string键的映射,并且希望查找一个键作为字符串文本的元素时。您总是必须构造动态std::string对象,即使std::string为比较运算符提供字符串文本。
因此,从C++14开始,还可以通过拼写std::set<int*, std::less<>>来生成一个具有非同构查找的集(或映射)。有了这样一个容器,循环函数就变成了模板,您确实可以比较不同类型的值(将转换逻辑留给底层的<-operator)。但是请注意,std::less<int*>需要为指针提供严格的弱排序,而std::less<>则不是,因此您可能会出现未定义的行为。
发布于 2018-10-27 17:13:40
set::find()用O(logN)给出答案,std::find()用O(N)给出答案。
同样,map::find()在O(logN)中给出了答案,而std::find()在O(N)中给出了答案。
https://stackoverflow.com/questions/32625976
复制相似问题