递归案例结束时的模板语法错误
Template syntax error with end of recursion case
有人能告诉我下面递归特化结束的语法有什么问题吗?我以为我遵守了所有规则。
#include <iostream>
template <typename StreamType = std::ostream, StreamType& stream = std::cout>
class StringList {
template <typename...> class AddStrings;
public:
template <typename... Args> void addStrings (Args&&... args) {AddStrings<Args...>()(args...);}
};
template <typename StreamType, StreamType& stream>
template <typename First, typename... Rest>
class StringList<StreamType, stream>::AddStrings<First, Rest...> : AddStrings<Rest...> {
public:
void operator()(First&& first, Rest&&... rest) {
// do whatever
AddStrings<Rest...>::operator()(std::forward<Rest>(rest)...);
}
};
template <typename StreamType, StreamType& stream>
template <>
class StringList<StreamType, stream>::AddStrings<> {
friend class StringStreamList;
void operator()() const {} // End of recursion.
};
int main() {
StringList<> stringList;
// stringList.addStrings ("dog", "cat", "bird");
}
我不明白错误信息:
Test.cpp:22:11: error: invalid explicit specialization before '>' token
template <>
^
Test.cpp:22:11: error: enclosing class templates are not explicitly specialized
Test.cpp:23:39: error: template parameters not used in partial specialization:
class StringList<StreamType, stream>::AddStrings<> {
^
Test.cpp:23:39: error: 'StreamType'
Test.cpp:23:39: error: 'stream'
这是重要的一点:
Test.cpp:22:11: error: enclosing class templates are not explicitly specialized
这意味着您不能为非特化模板的成员定义明确的特化。
class StringList<StreamType, stream>::AddStrings<> {
这里 AddStrings
是明确特化的,但 StringList
不是。这是不允许的。
尽管 Jonhathan Wakely 的建议有效,但对于那些强烈希望将 class 嵌套的人来说,因为它根本不会在其他任何地方使用,我想我们可以为 [=11= 插入一个虚拟模板参数].现在我将它保留在内部 class,因为我非常喜欢,现在可以编译以下内容:
#include <iostream>
template <typename StreamType = std::ostream, StreamType& stream = std::cout>
class StringList {
template <typename, typename...> struct AddStrings; // The first type is a dummy type.
public:
template <typename... Args> void addStrings (Args&&... args) {AddStrings<void, Args...>()(args...);}
};
template <typename StreamType, StreamType& stream>
template <typename T, typename First, typename... Rest>
class StringList<StreamType, stream>::AddStrings<T, First, Rest...> : AddStrings<T, Rest...> {
public:
void operator()(First&& first, Rest&&... rest) {
// do whatever
std::cout << first << ' ';
AddStrings<T, Rest...>::operator()(std::forward<Rest>(rest)...);
}
};
template <typename StreamType, StreamType& stream>
template <typename Dummy>
class StringList<StreamType, stream>::AddStrings<Dummy> {
public:
void operator()() const {} // End of recursion.
};
int main() {
StringList<> stringList;
stringList.addStrings ("dog", "cat", "bird");
}
有人能告诉我下面递归特化结束的语法有什么问题吗?我以为我遵守了所有规则。
#include <iostream>
template <typename StreamType = std::ostream, StreamType& stream = std::cout>
class StringList {
template <typename...> class AddStrings;
public:
template <typename... Args> void addStrings (Args&&... args) {AddStrings<Args...>()(args...);}
};
template <typename StreamType, StreamType& stream>
template <typename First, typename... Rest>
class StringList<StreamType, stream>::AddStrings<First, Rest...> : AddStrings<Rest...> {
public:
void operator()(First&& first, Rest&&... rest) {
// do whatever
AddStrings<Rest...>::operator()(std::forward<Rest>(rest)...);
}
};
template <typename StreamType, StreamType& stream>
template <>
class StringList<StreamType, stream>::AddStrings<> {
friend class StringStreamList;
void operator()() const {} // End of recursion.
};
int main() {
StringList<> stringList;
// stringList.addStrings ("dog", "cat", "bird");
}
我不明白错误信息:
Test.cpp:22:11: error: invalid explicit specialization before '>' token
template <>
^
Test.cpp:22:11: error: enclosing class templates are not explicitly specialized
Test.cpp:23:39: error: template parameters not used in partial specialization:
class StringList<StreamType, stream>::AddStrings<> {
^
Test.cpp:23:39: error: 'StreamType'
Test.cpp:23:39: error: 'stream'
这是重要的一点:
Test.cpp:22:11: error: enclosing class templates are not explicitly specialized
这意味着您不能为非特化模板的成员定义明确的特化。
class StringList<StreamType, stream>::AddStrings<> {
这里 AddStrings
是明确特化的,但 StringList
不是。这是不允许的。
尽管 Jonhathan Wakely 的建议有效,但对于那些强烈希望将 class 嵌套的人来说,因为它根本不会在其他任何地方使用,我想我们可以为 [=11= 插入一个虚拟模板参数].现在我将它保留在内部 class,因为我非常喜欢,现在可以编译以下内容:
#include <iostream>
template <typename StreamType = std::ostream, StreamType& stream = std::cout>
class StringList {
template <typename, typename...> struct AddStrings; // The first type is a dummy type.
public:
template <typename... Args> void addStrings (Args&&... args) {AddStrings<void, Args...>()(args...);}
};
template <typename StreamType, StreamType& stream>
template <typename T, typename First, typename... Rest>
class StringList<StreamType, stream>::AddStrings<T, First, Rest...> : AddStrings<T, Rest...> {
public:
void operator()(First&& first, Rest&&... rest) {
// do whatever
std::cout << first << ' ';
AddStrings<T, Rest...>::operator()(std::forward<Rest>(rest)...);
}
};
template <typename StreamType, StreamType& stream>
template <typename Dummy>
class StringList<StreamType, stream>::AddStrings<Dummy> {
public:
void operator()() const {} // End of recursion.
};
int main() {
StringList<> stringList;
stringList.addStrings ("dog", "cat", "bird");
}