我有一个模板类,如下所示
namespace binary_search_tree {
template <typename T>
class binary_tree {
private:
T d;
binary_tree<T> *l, *r;
public:
binary_tree(T d) : d(d), l(nullptr), r(nullptr)
{}
void insert(T d) {
binary_tree<T>* branch = new binary_tree<T>(d);
if(d <= this->d) {
this->l = branch;
} else {
this->r = branch;
}
}
const T data() const {
return d;
}
const binary_tree<T>* left() const {
return l;
}
const binary_tree<T>* right() const {
return r;
}
};
}我有一个用来测试我的类的test.cpp文件
#include "binary_search_tree.h"
#include "test/catch.hpp"
#include <vector>
// test data version: 1.0.0
template<typename T>
using tree_ptr = typename std::unique_ptr<binary_search_tree::binary_tree<T>>;
template<typename T>
static void test_leaf(const tree_ptr<T> &tree,
const T& data, bool has_left, bool has_right)
{
REQUIRE(data == tree->data()); // ***************
REQUIRE((bool) tree->left() == has_left); // <---- *** problem ***
REQUIRE((bool) tree->right() == has_right); // ***************
}
template<typename T>
static tree_ptr<T> make_tree(const std::vector<T> &data)
{
if (data.empty())
return tree_ptr<T>(nullptr);
auto data_iter = data.begin();
auto tree = tree_ptr<T>(new binary_search_tree::binary_tree<T>(*data_iter));
++data_iter;
for (; data_iter != data.end(); ++data_iter)
{
tree->insert(*data_iter);
}
return tree;
}
TEST_CASE("data_is_retained")
{
auto tested = make_tree<uint32_t>({4});
test_leaf<uint32_t>(tested, 4, false, false);
}
TEST_CASE("smaller_number_at_left_node")
{
auto tested = make_tree<uint32_t>({4, 2});
test_leaf<uint32_t>(tested, 4, true, false);
test_leaf<uint32_t>(tested->left(), 2, false, false);
}TEST_CASE()函数来自为测试而设计的单独的头文件。
当在test_leaf()函数中调用left()和right()时,问题就出现了。
编译器说
invalid initialization of reference of type ‘tree_ptr<unsigned int>&’ {aka ‘const
std::unique_ptr<binary_search_tree::binary_tree<unsigned int>,
std::default_delete<binary_search_tree::binary_tree<unsigned int> > >&’} from expression of
type ‘binary_search_tree::binary_tree<unsigned int>*’我不确定如何使这些类型匹配。我尝试过以各种方式返回引用,但这似乎使事情变得更糟。我应该返回一个unique_ptr<>吗?我对default_delete<>是什么感到困惑。在我看来,我应该返回某种类型的引用而不是指针。我不确定如何在我的课堂上安全地做到这一点。
发布于 2021-01-31 07:32:48
你的问题在这一行上:
test_leaf<uint32_t>(tested->left(), 2, false, false);binary_tree<T>::left返回一个指向树的左子树的原始的、非所属指针,但是test_leaf需要一个对std::unique_ptr<binary_tree<T>>的引用。
这里的解决方案是将test_leaf更改为接受原始指针或引用:
template<typename T>
static void test_leaf(binary_search_tree::binary_tree<T>& tree,
const T& data, bool has_left, bool has_right)
{
REQUIRE(data == tree.data());
REQUIRE(static_cast<bool>(tree.left()) == has_left);
REQUIRE(static_cast<bool>(tree.right()) == has_right);
}(请注意,tree的类型确实应该是const合格的,但是您的binary_tree类模板没有足够的const-correct来支持现在的实际工作)
然后,将调用test_leaf的所有位置改为传递对底层对象的引用。例如:
test_leaf<uint32_t>(tested, 4, true, false);
test_leaf<uint32_t>(tested->left(), 2, false, false);将更改为
test_leaf<uint32_t>(*tested, 4, true, false);
test_leaf<uint32_t>(*tested->left(), 2, false, false);通常,不假定指向对象的任何所有权的函数应接受对智能指针所拥有的对象的引用或原始指针。传递对智能指针本身的引用不会增加任何安全性,并且不必要地将函数的使用限制为仅由特定类型的智能指针拥有的动态分配的对象。
https://stackoverflow.com/questions/65973702
复制相似问题