# Sparse Configuration in C++ using Variadic Templates and Strong Types - published: 2020-09-23T18:35:06+0000 - tags: cpp, programming Let's consider data structure with well-defined default values. This structure is to be partially modified with different values on multiple places in the code base (especially in test code, where the same structure needs to be initialized with different data for each test case). ``` cpp struct ShapeParameters { unsigned stroke_color = 0x000000; double stroke_width = 1.0; unsigned fill_color = 0xffffff; double scale_x = 1.0; double scale_y = 1.0; double rotate = 0.0; }; ``` ### Strong Types So called strong types (inspired by [this post](https://www.fluentcpp.com/2016/12/08/strong-types-for-strong-interfaces/)) can be used to strictly constrain parameters of a function. As the quoted article states: > A strong type is a type used in place of another type to carry specific > meaning through its name. We can define following strong types for the above configuration structure. ``` cpp template struct NamedType { explicit NamedType(const T & v): value(v) { } T value; }; using StrokeColor = NamedType; using StrokeWidth = NamedType; using FillColor = NamedType; using ScaleX = NamedType; using ScaleY = NamedType; using Rotate = NamedType; ``` ### Variadic Template Configurator Now ve can define define variadic sparse configurator function as follows. ``` cpp inline void setParameter(ShapeParameters & sp, StrokeColor v) { sp.stroke_color = v.value; } inline void setParameter(ShapeParameters & sp, StrokeWidth v) { sp.stroke_width = v.value; } inline void setParameter(ShapeParameters & sp, FillColor v) { sp.fill_color = v.value; } inline void setParameter(ShapeParameters & sp, ScaleX v) { sp.scale_x = v.value; } inline void setParameter(ShapeParameters & sp, ScaleY v) { sp.scale_y = v.value; } inline void setParameter(ShapeParameters & sp, Rotate v) { sp.rotate = v.value; } template inline void setParameter( ShapeParameters & sp, T parameter, Args... others) { setParameter(sp, parameter); setParameter(sp, others...); } template inline void configure(ShapeParameters & sp, Args... parameters) { // do some initialization of the 'sp' here setParameter(sp, parameters...); } ``` ### Trying it Out By putting the above code together we can configure the parameters in single function call. ``` cpp int main() { ShapeParameters sp; configure(sp, StrokeColor(0xff0000), StrokeWidth(2.33), ScaleY(1.5)); std::cout << "Stroke color: " << sp.stroke_color << std::endl; std::cout << "Stroke width: " << sp.stroke_width << std::endl; std::cout << "Fill color: " << sp.fill_color << std::endl; std::cout << "Scale X: " << sp.scale_x << std::endl; std::cout << "Scale Y: " << sp.scale_y << std::endl; std::cout << "Rotate: " << sp.rotate << std::endl; return 0; } ```