为什么我不能返回带有透明函子的法线映射引用?
Why can't I return a normal map reference with a transparent functor?
这段代码有效:
class MyObj {};
class MyData {
public:
using tMyMap = std::map<uint64_t, std::shared_ptr<MyObj>>;
const tMyMap& get_normal() const;
const tMyMap& get_reverse() const;
private:
std::map<uint64_t, std::shared_ptr<MyObj>> _normal;
std::map<uint64_t, std::shared_ptr<MyObj>, std::less<uint64_t>> _reverse;
};
const MyData::tMyMap& get_normal() const { return _normal; }
const MyData::tMyMap& get_reverse() const { return _reverse; }
但是 clang-tidy 建议我在_reverse
声明中使用透明函子并将std::less<uint64_t>
更改为std::less<>
。不幸的是,当我这样做时,代码不再编译:
test_map.cpp: In member function ‘const tMyMap& MyData::get_reverse() const’:
test_map.cpp:20:60: error: invalid initialization of reference of type ‘const tMyMap& {aka const std::map<long unsigned int, std::shared_ptr<MyObj> >&}’ from expression of type ‘const std::map<long unsigned int, std::shared_ptr<MyObj>, std::less<void> >’
const MyData::tMyMap& MyData::get_reverse() const { return _reverse; }
该错误消息来自g ++,但clang给了我类似的错误。
为什么类型化函子没问题,但透明函子不编译?
std::map
的默认比较器是std::less<KeyType>
。
这意味着
std::map<uint64_t, T>
和
std::map<uint64_t, T, std::less<uint64_t>>
是相同的类型,但
std::map<uint64_t, T, std::less<>>
是一种不同的类型,因为std::less<uint64_t>
和std::less<>
是不同的类型。
如果_normal
和_reverse
实际上是相反的,您会看到同样的问题。 我假设你实际上打算宣布_reverse
std::map<uint64_t, std::shared_ptr<MyObj>, std::greater<uint64_t>> _reverse;
以便它以与_normal
相反的方向排序.
问题是比较函数是std::map
模板实例类型的一部分。std::map<K, T>
使用的比较函数的默认值为std::less<T>
。所以
std::map<uint64_t, std::shared_ptr<MyObj>, std::less<uint64_t>>
和
std::map<uint64_t, std::shared_ptr<MyObj>>
碰巧是相同的类型(第二个版本将使用比较函数的默认参数,结果是std::less<uint64_t>
(。但是,如果您使用std::less<>
(相当于std::less<void>
(作为_reverse
的比较函数,那么_normal
和_reverse
的类型将不再相同。只有_normal
仍然是tMyMap
类型,它使用默认的比较函数,而_reverse
将是不同的、不相关的类型。
如果MyData
的目的只是为了保存这两个映射,则可能需要考虑将其转换为结构:
struct MyData {
std::map<uint64_t, std::shared_ptr<MyObj>> normal;
std::map<uint64_t, std::shared_ptr<MyObj>, std::less<>> reverse;
};
或者只是使用auto
以避免重复每个地图的类型
class MyData {
public:
const auto& get_normal() const { return _normal; }
const auto& get_reverse() const { return _reverse; }
private:
std::map<uint64_t, std::shared_ptr<MyObj>> _normal;
std::map<uint64_t, std::shared_ptr<MyObj>, std::less<>> _reverse;
};
相关文章:
- 智能指针作为无序映射键,并通过引用进行比较
- 拥有映射的现代方法,该映射可以指向或引用已在堆栈上分配的不同类型的数据
- 从函数返回对映射的引用
- 为什么我不能返回带有透明函子的法线映射引用?
- 通过指针或引用将映射传递给函数?
- 将从std::映射中获取的std::pair引用传递给接受std::对引用的函数
- 映射/集迭代器不可取消引用 (C++) - 调试断言失败
- 取消引用映射迭代器时返回对临时的引用
- 有没有办法在不使用循环的情况下非具体地引用映射中的每个值?C++
- lambda 和映射,引用参数 - 编译错误
- 将引用对具有shared_ptr作为值的映射转换为对具有shared_ptr const 作为值的映射的引用
- Boost Intervocess:通过迭代通过从结构引用对象的映射进行迭代时
- 使用双迭代器引用映射中的列表
- 在消息映射中创建按钮和引用
- c++存储映射元组的引用,以便在另一个函数中使用
- 由引用集/映射迭代器传递的迭代器不可取消引用
- 本机C++类与 WinRT 组件(引用类)之间的自动映射
- 返回模板映射值作为引用
- SWIG 不可变标准::映射引用
- 同一个类使用的映射引用类