如果没有静态内联,函数中的默认参数不会 compile/link
Default parameter in a function wouldnt compile/link without static inline
我正在用 C++ 编写 BST class 并想向函数添加默认参数但是,当我尝试 visual studio 编译器时给出了编译和链接错误,所以过了一会儿通过谷歌搜索,我将根变量设置为静态内联并且它起作用了,我想知道在这种特定情况下静态内联会发生什么变化。
这是 BST class 代码:
#pragma once
template<typename T>
class BST
{
template<typename T>
struct node
{
T data;
node<T>* left;
node<T>* right;
node(T d)
{
data = d;
left = right = nullptr;
}
};
public:
BST()
{
root = nullptr;
}
~BST()
{
delete root;
}
node<T>* insert(T d)
{
if (root == nullptr)
{
root = new node<T>(d);
return root;
}
node<T>* current = root;
node<T>* k = nullptr;
while (current != nullptr)
{
k = current;
if (current->data > d)
{
current = current->left;
}
else if (current->data < d)
{
current = current->right;
}
}
if (k->data > d)
{
k->left = new node<T>(d);
}
else if (k->data < d)
{
k->right = new node<T>(d);
}
return root;
}
bool find(T d)
{
if (root == nullptr)
{
std::cerr << "Tree is empty! : ";
return false;
}
node<T>* current = root;
node<T>* k = nullptr;
while (current->data != d)
{
k = current;
if (current->left == nullptr || current->right == nullptr && current->data != d)
{
std::cout << "Not Found! : ";
return false;
}
if (current->data > d)
{
current = current->left;
}
else if (current->data < d)
{
current = current->right;
}
}
return true;
}
node<T>* findmax()
{
node<T>* temp = root;
while (temp->right != nullptr)
{
temp = temp->right;
}
return temp;
}
node<T>* findmin(node<T>* temp = root)
{
while (temp->left != nullptr)
{
temp = temp->left;
}
return temp;
}
private:
static inline node<T>* root;
};
根据 C++ 20 标准(9.3.4.7 默认参数)
- ...A non-static member shall not appear in a default argument unless it appears as the id-expression of a class member access expression
(7.6.1.5) or unless it is used to form a pointer to member
因此,当数据成员 root
未声明为静态时,此函数声明带有默认参数
node<T>* findmin(node<T>* temp = root)
不正确。
例如,您可以将函数声明为
node<T>* findmin(node<T>* temp = nullptr )
在这种情况下,您可以在函数中检查参数 temp 是否为空指针,如果是,您可以使用指针 root
.
为其赋值
这是因为
The keyword this shall not be used in a default argument of a member function
并且 class 的非静态成员绑定到 this
(即 root
等同于 this->root
)。更多关于默认参数限制 here.
对于您的情况,您可以采用以下解决方法:
node<T>* findmin(node<T>* temp = nullptr)
{
if (temp == nullptr) temp = root;
但是为了清楚起见,我不确定您是否应该使用它。
我正在用 C++ 编写 BST class 并想向函数添加默认参数但是,当我尝试 visual studio 编译器时给出了编译和链接错误,所以过了一会儿通过谷歌搜索,我将根变量设置为静态内联并且它起作用了,我想知道在这种特定情况下静态内联会发生什么变化。
这是 BST class 代码:
#pragma once
template<typename T>
class BST
{
template<typename T>
struct node
{
T data;
node<T>* left;
node<T>* right;
node(T d)
{
data = d;
left = right = nullptr;
}
};
public:
BST()
{
root = nullptr;
}
~BST()
{
delete root;
}
node<T>* insert(T d)
{
if (root == nullptr)
{
root = new node<T>(d);
return root;
}
node<T>* current = root;
node<T>* k = nullptr;
while (current != nullptr)
{
k = current;
if (current->data > d)
{
current = current->left;
}
else if (current->data < d)
{
current = current->right;
}
}
if (k->data > d)
{
k->left = new node<T>(d);
}
else if (k->data < d)
{
k->right = new node<T>(d);
}
return root;
}
bool find(T d)
{
if (root == nullptr)
{
std::cerr << "Tree is empty! : ";
return false;
}
node<T>* current = root;
node<T>* k = nullptr;
while (current->data != d)
{
k = current;
if (current->left == nullptr || current->right == nullptr && current->data != d)
{
std::cout << "Not Found! : ";
return false;
}
if (current->data > d)
{
current = current->left;
}
else if (current->data < d)
{
current = current->right;
}
}
return true;
}
node<T>* findmax()
{
node<T>* temp = root;
while (temp->right != nullptr)
{
temp = temp->right;
}
return temp;
}
node<T>* findmin(node<T>* temp = root)
{
while (temp->left != nullptr)
{
temp = temp->left;
}
return temp;
}
private:
static inline node<T>* root;
};
根据 C++ 20 标准(9.3.4.7 默认参数)
- ...A non-static member shall not appear in a default argument unless it appears as the id-expression of a class member access expression (7.6.1.5) or unless it is used to form a pointer to member
因此,当数据成员 root
未声明为静态时,此函数声明带有默认参数
node<T>* findmin(node<T>* temp = root)
不正确。
例如,您可以将函数声明为
node<T>* findmin(node<T>* temp = nullptr )
在这种情况下,您可以在函数中检查参数 temp 是否为空指针,如果是,您可以使用指针 root
.
这是因为
The keyword this shall not be used in a default argument of a member function
并且 class 的非静态成员绑定到 this
(即 root
等同于 this->root
)。更多关于默认参数限制 here.
对于您的情况,您可以采用以下解决方法:
node<T>* findmin(node<T>* temp = nullptr)
{
if (temp == nullptr) temp = root;
但是为了清楚起见,我不确定您是否应该使用它。