lambda型演绎失败

时间:2018-03-18 13:40:52

标签: c++ lambda c++14

有人想解释为什么这段代码对于模板函数不正确,但对普通函数效果很好。例如,如果我们用非模板函数替换std::copy,没问题。

如何更改代码并使其对模板和非模板函数都有效?

auto functionSpan = [](auto&& func, auto&&... args) {
    auto t1 = std::chrono::high_resolution_clock::now();
    std::forward<decltype(func)>(func)(std::forward<decltype(args)>(args)...);
    auto t2 = std::chrono::high_resolution_clock::now();
    return std::chrono::duration_cast<std::chrono::microseconds>(t2-t1).count();
};

vector<int> vec {1,2,3,4,5,6,7,8,9};
functionSpan(std::copy, vec.begin(), vec.end(), std::ostream_iterator<int>(std::cout, " "));

2 个答案:

答案 0 :(得分:1)

std :: copy不引用单个函数。您需要指定std::copy<Type>

答案 1 :(得分:0)

问题是std::copy(实际上,任何 template函数)不是常规函数,因此编译器无法派生它。编译器需要的是一个真正的函数,尽管你可以将参数标记为std::copy

明确标出参数的问题是你的代码不再是通用的,而且在处理迭代器时它很乏味且容易出错。相反,我建议稍微改变你的功能签名:

auto functionSpan = [](auto&& fn) {
    auto t1 = std::chrono::high_resolution_clock::now();
    fn();
    auto t2 = std::chrono::high_resolution_clock::now();
    return std::chrono::duration_cast<std::chrono::microseconds>(t2-t1).count();
};

auto copy_helper = [](auto && ... args) {
    return [args...]() {
        std::copy(args...);
    };
};

std::vector<int> vec {1,2,3,4,5,6,7,8,9};
functionSpan(copy_helper(vec.begin(), vec.end(),
                         std::ostream_iterator<int>(std::cout, " ")
                        ));

这为我编译(我删除了forward以使我的生活变得更简单)并按预期运行。你必须为每个template函数编写一个特定的帮助器,但它比试图删除template参数更少,因为你仍然可以获得大部分的类型推导。