C ++部分模板专业化-设计简化 [英] C++ Partial template specialization - design simplification

查看:76
本文介绍了C ++部分模板专业化-设计简化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究管道/数据流设计模式.我有一个类算法数据输出"(AlgorithmOutput),它充当两个连接的网段之间的接口.特别是,它提供了方法模板getOutput<size_t N>,用于从数据发送器"类型的对象输出的数据.

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'.

当前设计基于这样的想法:用户从类AlgorithmOutput派生并提供有限数量的方法模板getOutput<size_t N>的实现.我还需要能够允许用户通过方法getOutput提供他们自己的自定义返回类型(即返回类型不能是多态的).此外,必须具有getOutput的所有实现,才能访问定义为方法所属的类的成员的相同数据集.

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.

当前解决方案在用户派生的类中使用部分显式专门化来定义方法getOutput的不同实现.我想简化解决方案,并且希望在不丢失当前设计功能的情况下获得如何实现此想法的任何想法.

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.

从用户的角度来看,我仅关注方法getOutput的实现难易程度.我不担心基类的实现有多复杂.

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.

派生类的实现示例:

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;
            }
    };

};

推荐答案

您可以使用标签分派来避免部分专业化的需求.简化版:

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;
    }
};

这篇关于C ++部分模板专业化-设计简化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆