对称模板的参数

时间:2014-11-19 09:10:43

标签: c++ templates template-specialization

假设我们有一些转换例程类。如果我们可以从T类转换为U,我们会自动转换为反之亦然。

我用模板类和一些特化代表它:

template <typename T, typename U>
class Convert;

template <>
class Convert<A,B> {
    static int param() { return 42; }
}

template <>
class Convert<B,A> {
    static int param() { return -Convert<A,B>::param(); }
}

这很好,但是当我们需要为例程添加新类型时,我们必须添加2个特殊化。 我们可以通过定义一些通用的反向模板类来将该数字减少为1:

template <typename T, typename U>
class Convert {
    static int param() { return -Convert<U,T>::param(); }
}

如果我们已经有转换专业化,这可能有效吗?

提前致谢。

1 个答案:

答案 0 :(得分:1)

以下是我在评论中提出的建议:

#include<iostream>
#include<type_traits>

struct A{};
struct B{};
struct C{};

template <typename ... Args>
struct Convert;

template <typename T>
struct Convert<T,T> {
    static int param() { return 0; }
};

template <typename T, typename U>
struct Convert<T,U> {
    static decltype(-Convert<U,T>::param()) param() { return -Convert<U,T>::param(); }
};

template <>
struct Convert<A,B> {
    static int param() { return 42; }
};

template <>
struct Convert<A,C> {
    static int param() { return 43; }
};

template <>
struct Convert<B,C> {
    static int param() { return 44; }
};

int main()
{
    std::cout<<Convert<A,B>::param()<<std::endl;
    std::cout<<Convert<B,A>::param()<<std::endl;
    std::cout<<Convert<A,C>::param()<<std::endl;
    std::cout<<Convert<C,A>::param()<<std::endl;
    std::cout<<Convert<B,C>::param()<<std::endl;
    std::cout<<Convert<C,B>::param()<<std::endl;

    Convert<int,double>::param();
}

这个想法是一次给出一般声明,然后首先指定模板参数相等的情况(应该给出零)以及它们不同的情况,其中返回转换后的参数。 / p>

接下来,对于n个类,您需要为所有n*(n-1)/2 Convert类提供特化。 (如果需要,可以通过推导进一步简化)。