#include <utility>
// empty declaration with variable number of arguments
template<typename...>
struct hnode;
// specialization for 1 template argument
template<typename T>
struct hnode<T> {
T data;
std::nullptr_t next;
};
// specialization for multiple template arguments
template<typename T, typename... Rest>
struct hnode<T, Rest...> {
T data;
hnode<Rest...>* next;
};
template<typename T>
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);
}
ICAgICNpbmNsdWRlIDx1dGlsaXR5PgogICAgCiAgICAvLyBlbXB0eSBkZWNsYXJhdGlvbiB3aXRoIHZhcmlhYmxlIG51bWJlciBvZiBhcmd1bWVudHMKICAgIHRlbXBsYXRlPHR5cGVuYW1lLi4uPgogICAgc3RydWN0IGhub2RlOwogICAgCiAgICAvLyBzcGVjaWFsaXphdGlvbiBmb3IgMSB0ZW1wbGF0ZSBhcmd1bWVudAogICAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KICAgIHN0cnVjdCBobm9kZTxUPiB7CiAgICAgICAgVCBkYXRhOwogICAgICAgIHN0ZDo6bnVsbHB0cl90IG5leHQ7CiAgICB9OwogICAgCiAgICAvLyBzcGVjaWFsaXphdGlvbiBmb3IgbXVsdGlwbGUgdGVtcGxhdGUgYXJndW1lbnRzCiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZS4uLiBSZXN0PgogICAgc3RydWN0IGhub2RlPFQsIFJlc3QuLi4+IHsKICAgICAgICBUIGRhdGE7CiAgICAgICAgaG5vZGU8UmVzdC4uLj4qIG5leHQ7CiAgICB9OwogICAgCiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPgogICAgaG5vZGU8VD4gaGNvbnMoVCYmIHZhbCwgc3RkOjpudWxscHRyX3QpIHsKICAgICAgICByZXR1cm4geyBzdGQ6OmZvcndhcmQ8VD4odmFsKSwgbnVsbHB0ciB9OwogICAgfQogICAgCiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZS4uLiBSZXN0PgogICAgaG5vZGU8VCwgUmVzdC4uLj4gaGNvbnMoVCYmIHZhbCwgaG5vZGU8UmVzdC4uLj4mIG5leHQpIHsKICAgICAgICByZXR1cm4geyBzdGQ6OmZvcndhcmQ8VD4odmFsKSwgJm5leHQgfTsKICAgIH0KICAgIAogICAgaW50IG1haW4oKSB7CiAgICAgICAgaG5vZGU8aW50PiB0aHJlZSA9IGhjb25zKDEsIG51bGxwdHIpOwogICAgICAgIGF1dG8gdHdvID0gaGNvbnMoImhpIiwgdGhyZWUpOwogICAgfQ==