模板元编程与经典名称重载混合

时间:2016-03-16 19:24:37

标签: c++ c++11 overloading variadic-templates variadic-functions

我想制作一个简单的函数 - 应用程序到多个变量 - 一次性模板,它运行得很好,但我感觉不够满足。这是工作代码:

#include <iostream>

// generated for last (or the only) variable sent to apply_to_many template overload
template<class Fun, class Type>
void apply_to_many(Fun fun, Type& current)
{
    current = fun(current);
}

// variadic template + variadic arguments, fun is applied to 
// current variable, and template is generated for the rest
template<class Fun, class Type, class ...Types>
void apply_to_many(Fun fun, Type& current, Types&... other_variables)
{
    current = fun(current);
    if(sizeof...(other_variables) > 0)
        apply_to_many(fun, other_variables...);
}

// simple function returning square of value
int square(int x)
{
    return x*x;
}

int main()
{
    // some ints
    int a{3}, b{4}, c{5}, d{6}, e{7};

    std::cout << a << '\t'
              << b << '\t'
              << c << '\t'
              << d << '\t'
              << e << std::endl;

    apply_to_many(square, a, b, c, d, e);

    std::cout << a << '\t'
              << b << '\t'
              << c << '\t'
              << d << '\t'
              << e << std::endl;
}

输出:

3       4       5       6       7
9       16      25      36      49

虽然a b c d e可以是不同类型,例如intdoublecomplex<float>,但此处应用的功能仅适用于int s,因此int的平方如int s,float s的平方如int s,complex<float>平方如int s ...哦,complex<float>无法转换。关键是 - 使用为这些类型提供的经典重载会很好,例如std::sqrtstd::pow。但显然我们无法在没有明确选择一个重载的情况下将重载名称传递给模板。

apply_to_many(std::sqrt, a, b, c, d, e); //error

据我所知,我们不能发送模板函数作为参数(这将是惊人的,但可能很棘手)。我接受任何事情,甚至是宏观。

1 个答案:

答案 0 :(得分:4)

您可以使用通用lambda(C ++ 14):

apply_to_many([](auto v) { return std::sqrt(v); }, a, b, c, d, e);

Demo

在c ++ 11中,你必须以旧的方式创建你的仿函数:

struct Sqrt
{
    template <typename T>
    auto operator()(T value) const
    -> decltype(std::sqrt(value))
    {
        return std::sqrt(value);
    }
};

以后

apply_to_many(Sqrt{}, a, b, c, d, e);