我不擅长C++,所以这可能是初学者的错误。我正在尝试创建一个异构链接列表类型,在该列表中,每个节点的类型和其余部分的类型在每个节点中都已知。
以下是SSSCE:
#include <utility>
template<typename T, typename... Rest>
struct hnode {
T data;
hnode<Rest...>* next;
};
template<typename T>
struct hnode<T> {
T data;
std::nullptr_t next;
};
template<typename T, typename... Rest>
hnode<T> hcons(T&& val, std::nullptr_t) {
return { std::forward<T>(val), nullptr };
}
template<typename T, typename... Rest>
hnode<T, Rest...> hcons(T&& val, hnode<Rest...>& next) {
return { std::forward<T>(val), &next };
}
int main() {
hnode<int> three = hcons(1, nullptr);
auto two = hcons("hi", three);
}
然而,GCC对该代码给出了以下错误提示:
test.cc: In function ‘int main()’:
test.cc:28:29: error: no matching function for call to ‘hcons(const char [3], hnode<int>&)’
auto two = hcons("hi", three);
^
test.cc:28:29: note: candidates are:
test.cc:17:10: note: template<class T, class ... Rest> hnode<T> hcons(T&&, std::nullptr_t)
hnode<T> hcons(T&& val, std::nullptr_t) {
^
test.cc:17:10: note: template argument deduction/substitution failed:
test.cc:28:29: note: cannot convert ‘three’ (type ‘hnode<int>’) to type ‘std::nullptr_t’
auto two = hcons("hi", three);
^
test.cc:22:19: note: hnode<T, Rest ...> hcons(T&&, hnode<Rest ...>&) [with T = const char (&)[3]; Rest = {int, Rest}]
hnode<T, Rest...> hcons(T&& val, hnode<Rest...>& next) {
^
test.cc:22:19: note: no known conversion for argument 2 from ‘hnode<int>’ to ‘hnode<int, Rest>&’
Clang稍微简洁一些,但对于我来说仍然不够有帮助,无法修复它:
test.cc:28:12: error: no matching function for call to 'hcons'
auto two = hcons("hi", three);
^~~~~
test.cc:17:10: note: candidate function [with T = char const (&)[3], Rest = <>] not viable: no known conversion from 'hnode<int>' to 'std::nullptr_t' (aka 'nullptr_t') for 2nd argument
hnode<T> hcons(T&& val, std::nullptr_t) {
^
test.cc:22:19: note: candidate template ignored: substitution failure [with T = char const (&)[3], Rest = <>]: too few template arguments for class template 'hnode'
hnode<T, Rest...> hcons(T&& val, hnode<Rest...>& next) {
^ ~~~~~
1 error generated.
看起来很奇怪,因为它将Rest
推断为<>
,而明显应该是<int>
,并且在上一行中使用了<int>
,但是出现了从'hnode<int>'到'std::nullptr_t'的未知转换
错误。我犯了什么错误?
hcons
的第一个重载不需要参数包。 - David Ghcons
的第一个重载中删除无用的typename... Rest
,因为这样会破坏错误消息。尽管如此,它是无害的,也不是错误的原因。 - user3175411