14728

C++ Partial template specialization - design simplification

I am working on a pipeline/dataflow design pattern. I have a class 'algorithm data output' (AlgorithmOutput) that acts as an interface between two connected network segments. In particular, it provides method templates getOutput<size_t N> that are used for the data output from an object of the type 'data transmitter'.

The current design is based on the idea that users derive from the class AlgorithmOutput and provide a finite number of implementations of the method template getOutput<size_t N>. I also need to be able to allow users to provide their own custom return types from the method getOutput (i.e. the return type cannot be polymorphic). Moreover, it is necessary to have all implementations of getOutput to be able to access the same data set defined as a member of the class to which the methods belong.

The current solution uses partial explicit specialisation in the classes derived by the user to define the different implementations of the method getOutput. I would like to simplify the solution and would appreciate any ideas on how this can be done without losing the functionality of the current design.

EDIT: I am only concerned about the ease of implementation of the method getOutput from the perspective of the user. I am not concerned about how complex is the implementation of the base classes.

An example of the implementation of the derived class:

class PipeOutputClass: public AlgorithmOutput<PipeOutputClass> { public: template <size_t N> auto getOutput(size_t c_Idx) const { return getOutputImpl<N>::apply(this, c_Idx); } template<size_t N, typename S> friend struct getOutputImpl; template<size_t N, typename = void> struct getOutputImpl { static auto apply( PipeOutputClass const* p_Self, size_t c_Idx ) { throw std::runtime_error("Wrong template argument."); } }; template <typename S> struct getOutputImpl<0, S> { static std::unique_ptr<double> apply( PipeOutputClass const* p_Self, size_t c_Idx ) { std::unique_ptr<double> mydouble(new double(10)); return mydouble; } }; template <typename S> struct getOutputImpl<1, S> { static std::unique_ptr<int> apply( PipeOutputClass const* p_Self, size_t c_Idx ) { std::unique_ptr<int> myint(new int(3)); return myint; } }; };

Answer1:

You could use tag dispatching to avoid the need for partial specialization. A simplified version:

//we'll use this to overload functions based on a size_t template param template <size_t N> struct Size2Type{}; class PipeOutputClass { public: template <size_t N> auto getOutput(size_t c_Idx) const { //use Size2Type to tag dispatch return getOutputImpl(Size2Type<N>{}, c_Idx); } //default version for when we don't explicitly provide an overload template <size_t N> auto getOutputImpl(Size2Type<N>, size_t c_Idx) const { throw std::runtime_error("Wrong template argument."); } //overload for when N = 0 std::unique_ptr<double> getOutputImpl (Size2Type<0>, size_t c_Idx) const { std::unique_ptr<double> mydouble(new double(10)); return mydouble; } //overload for when N = 1 std::unique_ptr<int> getOutputImpl (Size2Type<1>, size_t c_Idx) const { std::unique_ptr<int> myint(new int(3)); return myint; } };

Recommend

  • In Docker Swarm mode is there any point in replicating a service more than the number of hosts avail
  • Expected consumption of open file descriptors in Hadoop 0.21.0
  • Efficient matching of text messages against thousands of regular expressions
  • REST Web Service - Dynamic Query Parameters
  • Implementation of random number generator [duplicate]
  • using pinentry-tty in a bash script (like read)
  • Google API - Redirect URI mismatch error
  • When interface inheritance in Java is useful?
  • C#: Import/Export Settings into/from a File
  • Disable Kendo Autocomplete
  • Cast between interfaces whose interface signatures are same
  • Django invalid literal for int() with base 10
  • Sequential (transactional) API calls in angular 4 with state management
  • xtable package: Skipping some rows in the output
  • Use of this Javascript
  • NHibernate Validation Localization with S#arp Architecture
  • Is there a javascript serializer for JSON.Net?
  • Javascript simulate pressing enter in input box
  • Read text file and split every line in MSBuild
  • How to make a tree having multiple type of nodes and each node can have multiple child nodes in java
  • C# - Serializing and deserializing static member
  • Bug in WPF DataGrid
  • Java applet as stand-alone Windows application?
  • Cassandra Data Model
  • Where to put my custom functions in Wordpress?
  • Redux, normalised entities and lodash merge
  • How to get next/previous record number?
  • Python: how to group similar lists together in a list of lists?
  • Buffer size for converting unsigned long to string
  • Codeigniter doesn't let me update entry, because some fields must be unique
  • Error creating VM instance in Google Compute Engine
  • How can I get HTML syntax highlighting in my editor for CakePHP?
  • how does django model after text[] in postgresql [duplicate]
  • Django query for large number of relationships
  • How to get NHibernate ISession to cache entity not retrieved by primary key
  • Why is Django giving me: 'first_name' is an invalid keyword argument for this function?
  • Binding checkboxes to object values in AngularJs
  • Observable and ngFor in Angular 2
  • How can I use `wmic` in a Windows PE script?
  • How to push additional view controllers onto NavigationController but keep the TabBar?