C++ 部分模板特化 - 设计简化

标签 c++ templates c++11 pipeline partial-specialization

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

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

当前的解决方案在用户派生的类中使用部分显式特化来定义方法的不同实现 getOutput 。我想简化解决方案,并且希望了解有关如何在不丢失当前设计功能的情况下完成此操作的任何想法。

编辑:我只关心该方法的实现难易程度getOutput从用户的角度来看。我不关心基类的实现有多复杂。

派生类的实现示例:

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

};

最佳答案

您可以使用标记分派(dispatch)来避免部分特化的需要。简化版本:

//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++ 部分模板特化 - 设计简化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29843398/

相关文章:

Java 泛型,支持 "Specialization"?与 C++ 模板的概念相似性?

c++ - 实现 TreeModel 时的 Gtk::TreeModel::iterator 用法

c++ - 是否可以将此 Rust 代码写入语义上等效的 C++ 代码?

c++ - 以下代码对于多线程增量计数器和打印是否是一个好的解决方案?

c++ - 正则表达式作为标记器 - 以分隔符开头的字符串

c++ - fatal error LNK1169 : one or more multiply defined symbols found (C++)

ruby-on-rails - Ruby 和客户端 JS 的模板语言

python - django 中非常简单的用户输入

javascript - 在 javascript 中创建全局 urls 对象是否是一种好习惯,以便在模板中轻松进行反向路由?

c++ - 如何在main之前强制初始化静态局部变量?