gpt4 book ai didi

c++ - 如何在不重载 `std::multiset` 、 `operator()` 、 `std::less` 的情况下为 `std::greater` 提供自定义比较器?

转载 作者:太空狗 更新时间:2023-10-29 20:01:37 25 4
gpt4 key购买 nike

我想要一个用于以下代码的自定义比较器。但是,我不允许重载 operator()std::lessstd::greater

我尝试使用 lambda 实现此目的,但 gcc 不允许我将 auto 用作非静态成员。还有其他方法可以实现吗?

#include <iostream>
#include <map>
#include <set>

class Test
{
public:
// bool operator () (const int lhs, const int rhs) { // not allowed
// return lhs > rhs;
// };
using list = std::multiset<int /*, Test*/>;
std::map<const char*, list> scripts;
};

int main()
{
Test t;
t.scripts["Linux"].insert(5);
t.scripts["Linux"].insert(8);
t.scripts["Linux"].insert(0);

for (auto a : t.scripts["Linux"]) {
std::cout << a << std::endl;
}

std::cout << "end";
}

编辑:使用 lambda

class Test 
{
public:
auto compare = [] (const int a, const int b) { return a < b;}
using list = std::multiset<int, compare>; //here
std::map<const char*, list> scripts;
};

错误:

'auto' not allowed in non-static class member
auto compare = [] (const int a, const int b) { return a < b;}

最佳答案

I want a custom comparator for the following code. However, I cannot overload operator(), std::less, std::greater.

我假设你不允许重载 operator()Test类,但可能是其他类的。如果是这样,创建一个内部 private重载 operator() 的仿函数这可能是别名的一部分 using list = std::multiset<int, Compare>;

class Test
{
private:
struct Compare
{
bool operator()(const int lhs, const int rhs) const /* noexcept */ { return lhs > rhs; }
};

public:
using list = std::multiset<int, Compare>;
std::map<std::string, list> scripts;
};

I tried to achieve these using lambdas but gcc won't allow me to use auto as a non-static member. Any other way to make this work?

更新:经过一段时间的研究后,我找到了一种可以使用 lambda 函数的方法。

想法是使用 decltypestd::multiset使用自定义 lambda 比较 作为 std::map 的键脚本。除此之外,提供一个包装器方法来将条目插入到 CustomMultiList 中。 .

完整示例代码:( See live )

#include <iostream>
#include <string>
#include <map>
#include <set>

// provide a lambda compare
const auto compare = [](int lhs, int rhs) noexcept { return lhs > rhs; };

class Test
{
private:
// make a std::multi set with custom compare function
std::multiset<int, decltype(compare)> dummy{ compare };
using CustomMultiList = decltype(dummy); // use the type for values of the map
public:
std::map<std::string, CustomMultiList> scripts{};
// warper method to insert the `std::multilist` entries to the corresponding keys
void emplace(const std::string& key, const int listEntry)
{
scripts.try_emplace(key, compare).first->second.emplace(listEntry);
}
// getter function for custom `std::multilist`
const CustomMultiList& getValueOf(const std::string& key) const noexcept
{
static CustomMultiList defaultEmptyList{ compare };
const auto iter = scripts.find(key);
return iter != scripts.cend() ? iter->second : defaultEmptyList;
}
};


int main()
{
Test t{};
// 1: insert using using wrapper emplace method
t.emplace(std::string{ "Linux" }, 5);
t.emplace(std::string{ "Linux" }, 8);
t.emplace(std::string{ "Linux" }, 0);


for (const auto a : t.getValueOf(std::string{ "Linux" }))
{
std::cout << a << '\n';
}
// 2: insert the `CustomMultiList` directly using `std::map::emplace`
std::multiset<int, decltype(compare)> valueSet{ compare };
valueSet.insert(1);
valueSet.insert(8);
valueSet.insert(5);
t.scripts.emplace(std::string{ "key2" }, valueSet);

// 3: since C++20 : use with std::map::operator[]
t.scripts["Linux"].insert(5);
t.scripts["Linux"].insert(8);
t.scripts["Linux"].insert(0);

return 0;
}

直到 lambda 不是 default constructable and copyable .但是, std::map::operator[] 确实要求 mapped_type copy constructible default constructible 。因此插入到 scripts 的值映射(即到 std::multiset<int, decltype(/*lambda compare*/)> )使用 std::map 的订阅运营商只能从 C++20 开始。

关于c++ - 如何在不重载 `std::multiset` 、 `operator()` 、 `std::less` 的情况下为 `std::greater` 提供自定义比较器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56400801/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com