C ++模板化模板演绎可以回避吗?

时间:2018-01-03 00:35:11

标签: c++ templates c++17 template-deduction

我有编译时的情况,可以通过使用宏来解决,但我想知道是否有更好的路线。这是一个非常简化的概念版本,用于说明目的(真实的东西还有更多的" Do"状态并在宏中使用一个开关):

int DoA(int a, int b)
{
    return a + b;
}

int DoB(int a, int b)
{
    return a - b;
}

template <typename F> int DoFunc1(int a, int b, F func)
{
    return func(a,b);
}

template <typename F> int DoFunc2 (int a, int b, F func)
{
    a *= 2;
    b++;
    return func(a,b);
}

#define ChooseFunc(type, a, b, func)  (((type)) ? (func)((a), (b), (DoA)) : (func)((a), (b), (DoB)))

int CallerA(bool state, int a, int b) 
{
    return ChooseFunc(state, a, b, DoFunc1);
}

int CallerB(bool state, int a, int b) 
{
    return ChooseFunc(state, a, b, DoFunc2);
}

现在我能够做的就是免除宏并使用这样的东西:

int ChooseFunc(bool type, int a, int b, auto func)
{
    if (type)
        return func(a, b, DoA);

    return func(a, b, DoB);
}

但显然这不会编译,因为编译器无法推断出模板类型。

问题是,有没有一种更好的方法呢?

2 个答案:

答案 0 :(得分:4)

写一个函子类

struct Func1 {
    template<typename F>
    int operator()(int a, int b, F func) { return DoFunc1(a, b, func); }
};

// Likewise for DoFunc2

然后传递一个仿函数。

答案 1 :(得分:0)

将函数编写为函数对象:

constexpr auto DoFunc1 = [](int a, int b, auto func)->int
{
    return func(a,b);
};

constexpr auto DoFunc2 = [](int a, int b, auto func)->int
{
    a *= 2;
    b++;
    return func(a,b);
};

使用这种方法,您可以保留ChooseFunc()功能模板。