I don't have Visual Studio to test, but I see the problem in your code so I'll tell you about that, and you can test on Visual Studio.
The problem is that, when you recurse into PushTypes<Tail...>();
and Tail...
is empty, you're calling, PushTypes<>();
. Notice that your base case, void PushTypes() {}
is not a template function, i.e. you can't call it via PushTypes<>();
.
Also note that you'll need a class template as a helper because we don't have partial specializations for function templates yet (hopefully it'll be coming soon).
But here's what you can do.
#include <typeinfo>
#include <vector>
class ParamChecker {
public:
/* Our type info structure. */
using Types = std::vector<const std::type_info *>;
/* Delegate work to PushTypesImpl<>. */
template <typename... Types>
void PushTypes() {
PushTypesImpl<Types...>()(types_);
}
private:
/* Forward declaration. */
template <typename... Types>
class PushTypesImpl;
/* Collection of type information. */
Types types_;
}; // ParamChecker
/* Base case. */
template <>
class ParamChecker::PushTypesImpl<> {
public:
void operator()(Types &) const { /* Do nothing. */ }
};
/* Recursive case. */
template <typename Head, typename... Tail>
class ParamChecker::PushTypesImpl<Head, Tail...> {
public:
void operator()(Types &types) const {
types.push_back(&typeid(Head));
PushTypesImpl<Tail...>()(types);
}
};
int main() {
ParamChecker x;
x.PushTypes<>(); // push nothing.
x.PushTypes<int>(); // push int.
x.PushTypes<int, double>(); // push int and double.
}
EDIT:
The following is an alternative approach using type_list
and passing it as an argument.
NOTE: The use of type_list<>
here instead of tuple<>
is because constructing an empty tuple requires that all of the types be default-constructable, and even if they were all default-constructable, we don't want to default-construct them for no reason.
template <typename... Types>
class type_list {};
class ParamChecker {
public:
/* Our type info structure. */
using Types = std::vector<const std::type_info *>;
/* Base case. Do nothing. */
void PushTypes(type_list<> &&) {}
/* Recursive case. */
template <typename Head, typename... Tail>
void PushTypes(type_list<Head, Tail...> &&) {
types_.push_back(&typeid(Head));
PushTypes(type_list<Tail...>());
}
private:
/* Collection of type information. */
Types types_;
}; // ParamChecker
int main() {
ParamChecker x;
x.PushTypes(type_list<>()); // push nothing.
x.PushTypes(type_list<int>()); // push int.
x.PushTypes(type_list<int, double>()); // push int and double.
}