【问题标题】:Template specialization when parameter values are equal参数值相等时的模板特化
【发布时间】:2013-05-31 21:15:28
【问题描述】:

我有表格的功能

template<int a, int b>
void f();

我想专攻 a == b。伪代码看起来像:

template<int a>
void f<a, a>(){ //something}

template<int a, int b>
void f<a, b>(){ //something different}

如果没有部分模板专业化问题,这可能吗?

编辑:感谢您的快速回复。该方法实际上是在一个类的内部,更像这样:

<typename a> class A{ 
    template<int b, int c> f(); 
}; 

A inst; 
inst.f<1,1>(); 
inst.f<1,2>(); 

【问题讨论】:

    标签: c++ templates template-specialization specialization


    【解决方案1】:

    您不能部分特化函数模板,但可以部分特化类模板。

    这为以下技巧留下了空间,其中实际工作由主函数模板和专用函数模板的静态成员函数完成,您的原始 f() 函数将其职责委托给它们:

    #include <iostream>
    
    namespace detail
    {
        template<int A, int B>
        struct helper
        {
            static void call() { std::cout << "f<A, B>()" << std::endl; }
        };
    
        template<int A>
        struct helper<A, A>
        {
            static void call() { std::cout << "f<A, A>()" << std::endl; }
        };
    }
    
    template<int a, int b>
    void f()
    {
        detail::helper<a, b>::call();
    }
    

    这就是您可以使用f() 函数模板的方式:

    int main()
    {
        f<1, 2>();
        f<1, 1>();
    }
    

    这是live example。

    编辑:

    如果你的函数模板是成员函数,事情会稍微复杂一些,但上面概述的将函数模板部分特化转换为类模板部分特化的解决方案仍然可行。

    这就是基于example provided in the comments 的方式。

    首先,前向声明helper类模板并授予其实例访问您的类模板A的私有成员的权限(附加类型参数T的作用稍后会变得清晰) :

    namespace detail
    {
        template<typename T, int A, int B>
        struct helper;
    }
    
    template <typename a>
    class A
    {
    public:
        template<int b, int c>
        void f();
    private:
        template<typename, int, int> friend struct detail::helper;
    };
    

    然后您将像以前一样定义helper 类模板及其特化,但向call() 函数添加一个函数参数,该函数类型是操作原始成员函数f() 具有的类对象所必需的类型被调用:

    namespace detail
    {
        template<typename T, int A, int B>
        struct helper
        {
            static void call(T* p) { std::cout << "f<A, B>()" << std::endl; }
        };
    
        template<typename T, int A>
        struct helper<T, A, A>
        {
            static void call(T* p) { std::cout << "f<A, A>()" << std::endl; }
        };
    }
    

    然后你可以定义成员函数f(),如下所示:

    template<typename a>
    template<int b, int c>
    void A<a>::f()
    {
        detail::helper<A<a>, b, c>::call(this);
    }
    

    并最终以这种方式使用它:

    int main()
    {
        A<int> inst;
        inst.f<1,1>();
        inst.f<1,2>();
    }
    

    这一切都放在了这个live example中。

    【讨论】:

    • 非常酷。我需要进行哪些更改才能将其用作类成员函数?因为我需要访问类成员,所以我不能使结构成为类的静态成员。
    • @BenJones:我不明白你的问题。似乎您正在谈论的场景与您在问题文本中显示的场景不同。你能澄清一下吗?
    • 当然。我可能过于简化了我正在尝试做的事情。我正在尝试做这样的事情: template class A{ template f(); };一个机构; inst.f(); inst.f();
    • @BenJones:你的评论被截断了。也许考虑编辑问题(或者如果编辑过于激进,可以提出一个新问题)
    • @BenJones:它会稍微复杂一些,但你仍然可以做到。我要编辑答案
    猜你喜欢
    • 1970-01-01
    • 2015-02-19
    • 1970-01-01
    • 1970-01-01
    • 2011-05-10
    • 1970-01-01
    • 2017-10-15
    • 2023-03-12
    相关资源
    最近更新 更多