The current implementation uses a fold expression to add all of the operations at once. This is really nice, but apparently the lifetime of each of the AbstractOperation instances is for the entire expression which may lead to a stack overflow for large numbers of operations. This splits the method in two to allow for the lifetime of the AbstractOperation to be properly scoped.
/// This method is used by derived classes to add their operations to the set.
///
template <typename... Args> void addOperations() {
- (void)std::initializer_list<int>{
- 0, (addOperation(AbstractOperation::get<Args>(*this)), 0)...};
+ (void)std::initializer_list<int>{0, (addOperation<Args>(), 0)...};
+ }
+ template <typename Arg> void addOperation() {
+ addOperation(AbstractOperation::get<Arg>(*this));
}
-
void addOperation(AbstractOperation opInfo);
/// Register a set of type classes with this dialect.