在C ++中减少模板化的类参数

时间:2016-05-06 14:30:06

标签: c++ templates

我有一个这样的课程:

template <unsigned int A, unsigned int B>
class Foo { ... };

Foo需要一个名为bar()的方法,但我需要专门研究它。对于一个案例,当A == B时,我希望它做一件事,否则就是其他事情。如果不在函数中编写if语句,我可以这样做吗?像:

Foo<A, A>::bar() { ... } and Foo<A, B>::bar() { ... }

2 个答案:

答案 0 :(得分:5)

你可以对你的班级进行部分专业化:

#include<cassert>

template<typename A, typename B>
struct S {
    void f(int i) { assert(i == 42); }
};

template<typename A>
struct S<A, A> {
    void f(int i) { assert(i == 0); }
};

int main() {
    S<int, double> s1;
    S<int, int> s2;
    s1.f(42);
    s2.f(0);
}

答案 1 :(得分:3)

部分特化的另一个解决方案是enable_if。我假设你有整数模板参数,但如果你有类型,你可以使用std::is_same<TA,TB>

此答案基于此处的解决方案:std::enable_if to conditionally compile a member function

http://coliru.stacked-crooked.com/a/692fbfff1b9d84e8

#include <iostream>
#include <string>

template <unsigned int A, unsigned int B>
class Foo { 
    public:

        template<unsigned int TA=A, unsigned int TB=B>
        typename std::enable_if< TA == TB >::type
        bar() {
         std::cout << "equal version = " << A << "  " << B << "\n";
        }

        template<unsigned int TA=A, unsigned int TB=B>
        typename std::enable_if< TA != TB >::type
        bar() {
         std::cout << "NON equal version = " << A << "  " << B << "\n";
        }
};

int main()
{
    Foo<1, 1> f1;
    f1.bar();

    Foo<1, 2> f2;
    f2.bar();    
    return 0;
}

输出:

equal version = 1  1
NON equal version = 1  2

键入的模板参数示例:

http://coliru.stacked-crooked.com/a/05d6a93480e870aa

#include <iostream>
#include <string>

template <typename A, typename B>
class Foo { 
    public:

        template<typename TA=A, typename TB=B>
        typename std::enable_if<std::is_same<TA, TB>::value>::type
        bar() {
         std::cout << "equal version" << "\n";
        }

        template<typename TA=A, typename TB=B>
        typename std::enable_if<!std::is_same<TA, TB>::value>::type
        bar() {

         // This will cause compilation error if this bar() overload is to be instantiated
         // but since it is not there is no compilation error
         typename TA::non_exists ii = 0;
         std::cout << "NON equal version" << "\n";
        }
};
int main()
{
    Foo<int, int> f1;
    f1.bar();

    //Foo<int, float> f2;
    //f2.bar();    
    return 0;
}