I'd say it is... though, not in the way you want.
Rather than defining a bunch of overloads based on the parameter pack, my solution basically involves just doing
createNewClassInstance as a template function (i.e., a function with infinite overloads), and using
std::enable_if to 'remove' a function if called with a type that isn't in the argument pack:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
#include "SomeListClass.h"
#include <type_traits>
// helper to check all args eval to true
constexpr bool is_all_true() { return true; }
template <typename ...Args>
constexpr bool is_all_true(bool first, Args... rest) {
return first && is_all_true(rest...);
}
// class template
template <typename ...Args>
class VariadicPatternProviderInterface {
static_assert(sizeof...(Args) > 0, "Must provide at least one parameter");
public:
// Add a new class instance. If you need to, you can change the
// std::is_same to std::is_base_of or something, too.
// If you want better error messages, consider if replacing the std::enable_if
// with a static_assert in the function body would be appropriate for you.
template <typename T>
std::enable_if<is_all_true(std::is_same<T, Args>...)>::type
createNewClassInstance(T* pointer) {
TemplatePatternPointer* pointer = new T(); // ? This shadows function param
patternInstances.append(pointer);
}
void initPatterns() {
// some hackery to expand a list of void-returning function calls
using expand_type = int[];
(void) expand_type { (patternInstances.append(new Args), 0)... };
}
protected:
SomeListClass<TemplatePatternPointer*> patternInstances;
};
|
I'm sure there's a simpler and 'prettier' way of doing it this way, but that's what I thought of. Also note that that's completely untested code, and may not even work at all. You should get the general idea, though.
2. What syntax do I use for cycling through the template parameter pack? |
To cycle through a template parameter pack, the way to do is a recursive template declaration. Often it can be hard to work out how to apply it in a particular circumstance, though. My code above has an example of doing something like it with my
is_all_true function.