C++ 使用 shared_ptr 但调用对象的关系运算符?
C++ using shared_ptr but having my object's relational operators called?
我正在编写自己的堆class。我的模板化堆 class 要求在模板类型上定义运算符“>”和“<”。
在使用我编写的示例实例 class 时,一切似乎都运行良好(并且在 int 上也运行良好)。但是,由于 class 实例从堆中的不同节点移动,因此实例的构造如此之多,我决定看看当我创建 class 的 shared_ptr 堆时发生了什么.虽然我确实看到构造的实例数量下降了,但堆没有正常工作,因为智能指针 '>' 和 '<' 正在被调用,我猜这只是比较智能指针引用。
想到的一个解决方案是允许比较类型,就像许多 stl 类型一样,这样我就可以将自己的比较类型传递到堆 class 中,这将取消引用 shared_ptr 并调用基础类型上的操作。
我在 shared_ptr 上阅读的一些文档说它们实现了关系运算符(即 <),因此它们可以用作关联容器中的键。我正在考虑什么时候我可能想使用 shared_ptr 作为密钥而不是拥有自己的特定密钥。
我的样本类型堆似乎工作正常:
heap<foo> foo_heap(heap_type::max);
for (unsigned int i = 0; i < 10; ++i)
{
std::string s = "string ";
s += ('0' + i);
foo f(i, s);
foo_heap.push(f);
}
cout << "root: " << foo_heap.top() << endl;
将我的示例 class 包装在一个 shared_ptr 中,但这是行不通的,例如。就我要完成的任务而言,未满足堆约束。
heap<shared_ptr<foo>> foo_heap_smart(heap_type::max);
for (unsigned int i = 0; i < 10; ++i)
{
std::string s = "string ";
s += ('0' + i);
shared_ptr<foo> f(new foo(i, s));
foo_heap_smart.push(f);
}
cout << "root: " << *(foo_heap_smart.top()) << endl;
我的示例 foo class:
class foo
{
public:
foo(int value, std::string s) : _value(value), _s(s)
{
std::cout << "foo::foo()" << std::endl;
}
foo(const foo& f) : _value(f._value), _s(f._s)
{
std::cout << "foo::foo(const foo& f)" << std::endl;
}
~foo()
{
std::cout << "foo::~foo()" << std::endl;
}
virtual void operator=(const foo& f)
{
std::cout << "foo::operator=()" << std::endl;
this->_value = f._value;
this->_s = f._s;
}
virtual bool operator<(const foo& right)
{
return this->_value < right._value;
}
virtual bool operator>(const foo& right)
{
return this->_value > right._value;
}
void print(ostream& stm) const
{
stm << "value: " << this->_value << ", s: " << this->_s;
}
private:
int _value;
std::string _s;
};
所以我假设很多人 运行 遇到了类似的问题。只是想知道规定的解决方案是什么。正如我提到的,我想我知道出现的问题可能是一个很好的解决方案,但我想检查一下,因为智能指针似乎会因为它们实现关系运算符而导致很多问题。
谢谢,
尼克
规定的解决方案是,如果默认版本不适合您的需要,请提供您自己的比较运算符版本。 heap
class 的更好设计是也采用 Comparator
类型,它可以默认为 std::less
.
template <typename T, typename Comp = std::less<T>>
class heap {
...
};
现在为您提供专用于 shared_ptr
的 less
版本。
template <typename T>
struct less<shared_ptr<T>> {
bool operator()(const shared_ptr<T>& a, const shared_ptr<T>& b) const {
*a < *b;
}
};
为了更好的设计,您可以添加一些元编程 hack,使其仅适用于可以比较的类型 T
。
我正在编写自己的堆class。我的模板化堆 class 要求在模板类型上定义运算符“>”和“<”。
在使用我编写的示例实例 class 时,一切似乎都运行良好(并且在 int 上也运行良好)。但是,由于 class 实例从堆中的不同节点移动,因此实例的构造如此之多,我决定看看当我创建 class 的 shared_ptr 堆时发生了什么.虽然我确实看到构造的实例数量下降了,但堆没有正常工作,因为智能指针 '>' 和 '<' 正在被调用,我猜这只是比较智能指针引用。
想到的一个解决方案是允许比较类型,就像许多 stl 类型一样,这样我就可以将自己的比较类型传递到堆 class 中,这将取消引用 shared_ptr 并调用基础类型上的操作。
我在 shared_ptr 上阅读的一些文档说它们实现了关系运算符(即 <),因此它们可以用作关联容器中的键。我正在考虑什么时候我可能想使用 shared_ptr 作为密钥而不是拥有自己的特定密钥。
我的样本类型堆似乎工作正常:
heap<foo> foo_heap(heap_type::max);
for (unsigned int i = 0; i < 10; ++i)
{
std::string s = "string ";
s += ('0' + i);
foo f(i, s);
foo_heap.push(f);
}
cout << "root: " << foo_heap.top() << endl;
将我的示例 class 包装在一个 shared_ptr 中,但这是行不通的,例如。就我要完成的任务而言,未满足堆约束。
heap<shared_ptr<foo>> foo_heap_smart(heap_type::max);
for (unsigned int i = 0; i < 10; ++i)
{
std::string s = "string ";
s += ('0' + i);
shared_ptr<foo> f(new foo(i, s));
foo_heap_smart.push(f);
}
cout << "root: " << *(foo_heap_smart.top()) << endl;
我的示例 foo class:
class foo
{
public:
foo(int value, std::string s) : _value(value), _s(s)
{
std::cout << "foo::foo()" << std::endl;
}
foo(const foo& f) : _value(f._value), _s(f._s)
{
std::cout << "foo::foo(const foo& f)" << std::endl;
}
~foo()
{
std::cout << "foo::~foo()" << std::endl;
}
virtual void operator=(const foo& f)
{
std::cout << "foo::operator=()" << std::endl;
this->_value = f._value;
this->_s = f._s;
}
virtual bool operator<(const foo& right)
{
return this->_value < right._value;
}
virtual bool operator>(const foo& right)
{
return this->_value > right._value;
}
void print(ostream& stm) const
{
stm << "value: " << this->_value << ", s: " << this->_s;
}
private:
int _value;
std::string _s;
};
所以我假设很多人 运行 遇到了类似的问题。只是想知道规定的解决方案是什么。正如我提到的,我想我知道出现的问题可能是一个很好的解决方案,但我想检查一下,因为智能指针似乎会因为它们实现关系运算符而导致很多问题。
谢谢, 尼克
规定的解决方案是,如果默认版本不适合您的需要,请提供您自己的比较运算符版本。 heap
class 的更好设计是也采用 Comparator
类型,它可以默认为 std::less
.
template <typename T, typename Comp = std::less<T>>
class heap {
...
};
现在为您提供专用于 shared_ptr
的 less
版本。
template <typename T>
struct less<shared_ptr<T>> {
bool operator()(const shared_ptr<T>& a, const shared_ptr<T>& b) const {
*a < *b;
}
};
为了更好的设计,您可以添加一些元编程 hack,使其仅适用于可以比较的类型 T
。