我正在尝试为二叉树操作制作项目,以下是类原型(prototype)以及我遇到问题的代码。
BinaryTree.h 文件中的 BinaryTree 类
template <class T>
class BinaryTree
{
public:
BinaryTree();
BinaryTree(T);
};
BinaryTree.cpp中的构造函数实现
template<class T>
struct isPointer
{
static const bool value=false;
};
template<class T>
struct isPointer<T*>
{
static const bool value=true;
};
template<class T>
BinaryTree<T>::BinaryTree():root(nullptr)
{
//ctor
}
template<class T>
BinaryTree<T>::BinaryTree(T data)
{
if(isPointer<T>::value == true)
{
if(data != nullptr)
{
//Do something
}
}
}
BinaryTreeOperations 类继承 BinaryTree 类,其原型(prototype)定义在 BinaryTreeOperations.h
template<class T>
class BinaryTreeOperations:public BinaryTree<T>
{
public:
//Constructors
BinaryTreeOperations();
BinaryTreeOperations(T);
};
虽然构造函数是在 BinaryTreeOperations.cpp 类中定义的
template<class T>
BinaryTreeOperations<T>::BinaryTreeOperations(T data):BinaryTree<T>(data)
{
//ctor
}
Main.cpp文件中的main函数
int main()
{
cout << "Hello world!" << endl;
BinaryTreeOperations<std::string> b("1");
}
现在 g++ 抛出的错误是
no match for 'operator!=' (operand types are 'std::__cxx11::basic_string' and 'std::nullptr_t')
在行
if(data != nullptr)
在BinaryTree.cpp类中定义的BinaryTree构造函数
问题来了。我已经定义了 isPointer 结构来检查给定的模板是否是指针。但看起来,尽管 T 是 std::string g++ 仍在 if(isPointer<T>::value == true)
中
健康)状况。
我不明白我做错了什么?任何形式的指导将不胜感激。
最佳答案
这是一个案例 constexpr if (C++17) 会是一个很好的补充:您的分支将在编译时针对您传递的每个 T 进行评估。
一个可能的解决方法是利用 enable_if并根据 isPointer
谓词的结果定义两个构造函数版本,并让 SFINAE做好自己的工作
template <class T>
class BinaryTree
{
public:
BinaryTree();
template<typename TT = T>
BinaryTree(TT, typename std::enable_if<!isPointer<TT>::value>::type * = nullptr) {
}
template<typename TT = T>
BinaryTree(TT data, typename std::enable_if<isPointer<TT>::value>::type * = nullptr) {
if (data != nullptr)
{
//Do something (this is a pointer)
}
}
};
或者重构您的代码,记住模板实际上就是一个模板,并且在实例化时,它将在任何代码分支上为其参数生成代码定义。
关于C++ - 模板 is_Pointer 似乎失败的奇怪情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40845500/