c ++函数映射实现

use*_*904 5 c++ templates functional-programming map c++11

我一直在使用新的c ++标准中的可变参数模板,并提出了一个map函数(header +使用decs除外):

template<typename T>
T square(T i)
{
        return i * i;
}

template <typename T, typename... Ts>
const tuple<Ts...> map(const T f, const Ts...args)
{
        return make_tuple(f(args)...);
}

int main(int c, char *argv[])
{
        tuple<int, int> t;
        int (*fp) (int) = square;

        t = map(fp, 6, 8);

        cout <<get<0>(t) <<endl;
        cout <<get<1>(t) <<endl;

        return 0;
}
Run Code Online (Sandbox Code Playgroud)

哪个有效.只要所有参数都是map的相同类型.如果我更改主要使用稍微更一般的形式:

 tuple<int, float> t;

 t = map(square, 6, 8.0f);
Run Code Online (Sandbox Code Playgroud)

gcc 4.4报告:

In function ‘int main(int, char**)’:
error: no matching function for call to ‘map(<unresolved overloaded function type>, int, float)’
Run Code Online (Sandbox Code Playgroud)

任何想法如何使这项工作?

Soa*_*Box 5

首先,您不能将未解析的函数模板作为指针(或模板参数)传递,您只能传递它的实例.这意味着你的模板的第一个参数int (*)(int)在这个例子中被传递,并且它不能调用float (*)(float)实例化.我不确定解决这个问题的最佳方法,但无论如何,从技术上讲,你所询问的并不是这样.

我没有编译器来测试它,但我认为如果你std::function用来推断你传入的函数所需的类型,你可能能够将参数转换为函数.像这样:

template<typename T, typename Ts...>
tuple<Ts...> map(std::function<T (T)> const &f, Ts... args) {
    return make_tuple(static_cast<Ts>(f(static_cast<T>(args)))...);
}
Run Code Online (Sandbox Code Playgroud)

看,我认为你需要为函数转换参数(作为a T)和返回类型(作为a Ts),因为看起来一些隐式转换规则在这个模板中不起作用.

如果我的语法不起作用(可能没有,...当你没有编译器时s很棘手),你可能会把它重写为一个更冗长的函数,它Ts在调用之前解包每个函数.函数,然后建立一个元组.我不确定这是否真的有必要,但我的感觉是编译器对所有...解包的支持现在有点不稳定,所以即使你想出一些应该有用的东西,如果你的话我也不会感到惊讶编译器无法处理它.