这是我尝试创建一个简单的 constexpr 链表 -
struct Node
{
constexpr Node(const int n, Node const* next = nullptr)
: value(n), next(next) {}
constexpr Node push(const int n) const { return Node(n, this); }
int value;
Node const* next;
};
constexpr auto getSum(Node n) {
int sum = 0;
Node *current = &n;
while(current != nullptr) {
sum += current->value;
current = current->next;
}
return sum;
}
int main() {
constexpr Node a(0);
a.push(1);
a.push(22);
constexpr auto result = getSum(a);
return result;
}
编译此程序时,显示以下错误
prog.cc: In function 'constexpr auto getSum(Node)':
prog.cc:16:28: error: invalid conversion from 'const Node*' to 'Node*' [-fpermissive]
current = current->next;
~~~~~~~~~^~~~
prog.cc: In function 'int main()':
prog.cc:25:35: in constexpr expansion of 'getSum(a)'
prog.cc:16:28: error: conversion of 'const Node*' null pointer to 'Node*' is not a constant expression
我应该如何继续解决此问题并生成此类链表?这是用于在线查看执行的Wandbox链接。
直接错误很容易修复:
Node const *current = &n;
// ^^^^^
抱怨是current = current->next;
正在为Node *
分配Node const*
,所以不要这样做。
这样做会使你的程序编译但打印0
,因为push
调用都a
修改。您也不能将push
的结果存储为constexpr
,因为a
的地址(自动局部变量(不是常量表达式。
但是,您可以形成临时节点的链接列表并立即使用它:
constexpr auto result = getSum(a.push(1).push(22).push(19)); // OK, 42
正如@hg_git在您的帖子评论中指出的那样,constexpr
链表是不可能的。
我清理了您的代码以出现有用的错误。
#include <iostream>
struct Node
{
constexpr Node(const int n, Node * next = nullptr)
: value(n), next(next) {}
constexpr Node push(const int n) { return Node(n, this); }
int value;
Node * next;
};
constexpr auto getSum(Node n) {
int sum = 0;
Node *current = &n;
while(current != nullptr) {
sum += current->value;
current = current->next;
}
return sum;
}
int main() {
constexpr Node a(0);
a.push(1);
a.push(22);
constexpr auto result = getSum(a);
return result;
}
给这个
main.cpp: In function 'int main()':
main.cpp:25:13: error: passing 'const Node' as 'this' argument discards qualifiers [-fpermissive]
a.push(1);
^
main.cpp:7:20: note: in call to 'constexpr Node Node::push(int)'
constexpr Node push(const int n) { return Node(n, this); }
^~~~
main.cpp:26:14: error: passing 'const Node' as 'this' argument discards qualifiers [-fpermissive]
a.push(22);
^
main.cpp:7:20: note: in call to 'constexpr Node Node::push(int)'
constexpr Node push(const int n) { return Node(n, this); }
如您所见,即使关键字const
不存在,const 参数仍然存在一些问题。这是因为 constexpr 是在编译时计算的。从而使它们在运行时不可变。
链表可能会在运行时更改;如果为每个示例添加或删除节点。 因此,在这种情况下constexpr
不是正确的选择。
编辑: 这是您的代码的现场演示,从constexpr
中清除。我添加了一些评论,如果您不理解一行或功能,请随时询问。