C++ lambda型演绎失败

C++ lambda型演绎失败,c++,lambda,c++14,C++,Lambda,C++14,有人想解释一下为什么这段代码对于模板函数是不正确的,但是对于普通函数却很有效。例如,如果我们用非模板函数替换std::copy,就没有问题 如何更改代码并使其对模板和非模板函数都有效 auto functionSpan = [](auto&& func, auto&&... args) { auto t1 = std::chrono::high_resolution_clock::now(); std::forward<decltype(fu

有人想解释一下为什么这段代码对于模板函数是不正确的,但是对于普通函数却很有效。例如,如果我们用非模板函数替换
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, " "));
auto functionSpan=[](自动和函数、自动和…参数){
自动t1=std::chrono::高分辨率时钟::现在();
标准::转发(func)(标准::转发(args)…);
自动t2=标准::时钟::高分辨率时钟::现在();
返回std::chrono::duration_cast(t2-t1).count();
};
向量向量{1,2,3,4,5,6,7,8,9};
函数span(std::copy,vec.begin(),vec.end(),std::ostream_迭代器(std::cout,“”);

std::copy不引用单个函数。您需要指定
std::copy
问题是
std::copy
(实际上,任何
模板
函数)都不是常规函数,因此编译器无法派生它。编译器需要的是一个真正的函数,尽管您可以去掉
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, " ")
                        ));
自动功能span=[](自动和&fn){
自动t1=std::chrono::高分辨率时钟::现在();
fn();
自动t2=标准::时钟::高分辨率时钟::现在();
返回std::chrono::duration_cast(t2-t1).count();
};
自动复制\u helper=[](自动和…参数){
返回[args…](){
std::复制(args…);
};
};
向量向量{1,2,3,4,5,6,7,8,9};
functionSpan(复制辅助对象(vec.begin(),vec.end(),
std::ostream_迭代器(std::cout,“”)
));
这为我编译(我删除了
forward
ing以简化我的生活)并按预期运行。您必须为每个
template
函数编写一个特定的帮助程序,但它不像试图消除
template
参数那样简单,因为您仍然可以得到大部分类型推断。

functionSpan([&]{std::copy(vec.begin(),vec.end(),std::ostream_迭代器(std::cout,”);})