对于下面的简化代码片段:
template <typename T>
struct LinkedList {
struct Node {
explicit Node(const T& tdata) :
next{nullptr}, data{std::make_shared<T>(tdata)} {}
std::unique_ptr<Node> next;
std::shared_ptr<T> data;
};
std::unique_ptr<Node> head;
};
我想要一个std::queue<T>
,其中T与LinkedList::Node::data
的类型相同。
以下显式定义有效:
template <typename T> using SPQ
= std::queue<std::shared_ptr<T>>; // WORKS
但是以下所有内容都无法在couldn't infer template argument 'T'
的调用网站上进行编译:
template <typename T> using SPQ
= std::queue<typename std::common_type<decltype(LinkedList<T>::Node::data)>::type>; // FAIL!
template <typename T> using SPQ
= typename std::template queue<decltype(LinkedList<T>::Node::data)>; // FAIL!
template <typename T> using SPQ
= std::queue<decltype(LinkedList<T>::Node::data)>; // FAIL!
e.g。致电网站代码:
template <typename T>
void _Walk(const typename LinkedList<T>::Node& node, SPQ<T>& result) {
result.emplace(node.data);
const auto& next = node.next;
if (next) {
_Walk(*next, result);
}
}
template <typename T>
SPQ<T> Walk(const LinkedList<T>& ll) {
SPQ<T> result;
const auto& head = ll.head;
result.emplace(head->data);
const auto& next = head->next;
if (next) {
_Walk(*next, result);
}
return result;
}
LinkedList<int64_t> _MakeLL() {
int64_t rootData = 0;
LinkedList<int64_t> ll;
ll.head = std::make_unique<LinkedList<int64_t>::Node>(rootData);
ll.head->next = std::make_unique<LinkedList<int64_t>::Node>(1);
ll.head->next->next = std::make_unique<LinkedList<int64_t>::Node>(2);
ll.head->next->next->next = std::make_unique<LinkedList<int64_t>::Node>(4);
return ll;
}
template <typename T>
void _PrintResult(SPQ<T>& result, const std::string& msg) {
std::cout << msg;
while (result.size()) {
std::cout << *result.front() << ", ";
result.pop();
}
std::cout << '\n';
}
void Test() {
auto ll = _MakeLL();
auto result = Walk(ll);
_PrintResult(result, "Walking: ");
}
int main(int /*argc*/, char * /*argv*/[]) {
Test();
std::cout.flush();
return 0;
}
使用clang++ -std=c++14
编译会导致以下错误:
infer-templ-arg.cpp|80 col 2| error: no matching function for call to '_PrintResult'
|| _PrintResult(result, "Walking: ");
|| ^~~~~~~~~~~~
infer-templ-arg.cpp|68 col 6| note: candidate template ignored: couldn't infer template argument 'T'
|| void _PrintResult(SPQ<T>& result, const std::string& msg) {
|| ^
infer-templ-arg.cpp|50 col 3| error: no matching function for call to '_Walk'
|| _Walk(*next, result);
|| ^~~~~
infer-templ-arg.cpp|79 col 16| note: in instantiation of function template specialization 'Walk<long>' requested here
|| auto result = Walk(ll);
|| ^
infer-templ-arg.cpp|34 col 6| note: candidate template ignored: couldn't infer template argument 'T'
|| void _Walk(const typename LinkedList<T>::Node& node, SPQ<T>& result) {
|| ^
|| 2 errors generated.
使用g ++ 7.1.0进行编译会导致类似的错误。
那么,是否可以使队列元素与LinkedList<T>::Node::data
的类型相同,而不是明确地声明它?如果是这样,我将如何实现这一目标?