【问题标题】:c++ functional, std::function with generic parameterc++ 函数式,带有泛型参数的 std::function
【发布时间】:2018-04-09 11:57:49
【问题描述】:

我尝试编写一个 forEach 方法(我知道已经存在但我会自己尝试)

这是我的代码:

#include <iostream>
#include <array>
#include <functional>

using namespace std;

template<typename T, std::size_t SIZE>
void forEach(std::array<T, SIZE> array, function<void(int)> fun){
    for(auto const & object: array)
        fun(object);
}

int main()
{
    std::array<int, 4> num{1,2,3,4};

    forEach(num, [](int n) -> void { cout << n * n << endl;});

    return 0;
}

这很好用。

现在,当我将 forEach function&lt;void(int)&gt; fun 的第二个参数更改为 function&lt;void(T)&gt; fun 时,它无法编译并且出现错误:
no matching function for call to 'forEach(std::array&lt;int, 4u&gt;&amp;, main()::&lt;lambda(int)&gt;)'

但是当我正确理解时,T 在这个例子中应该是int
我会犯思维错误吗?
为什么它不起作用?

当我这样做时它会起作用:

template<typename T, std::size_t SIZE>
void forEach(std::array<T, SIZE> array, function<void(T)> fun){
    for(auto const & object: array)
        fun(object);
}

int main()
{
    std::array<int, 4> num{1,2,3,4};
    function<void(int)> func = [](int n) -> void { cout << n * n << endl;};
    forEach(num, func);

    return 0;
}

但是我可以像第一个代码sn-p那样直接在函数调用中做吗?

提前致谢

【问题讨论】:

  • Lambda 不是std::function,所以没有有效的扣除。
  • 但是当 lambda 不是 std::function 时,为什么这在参数中起作用:function&lt;void(int)&gt; fun
  • 可能重复:[我无法将 lambda 作为 std::function 传递](stackoverflow.com/questions/36030589/…)
  • 我猜第二个有效,因为存在隐式转换。在模板类型推导中,没有隐式转换,因此失败。当直接指定类型时,它就像现在从 lambda 到 std::function 的隐式转换一样。

标签: c++


【解决方案1】:

也许想得更笼统?

std::function 只是一种函数对象,它的限制很大。

#include <iostream>
#include <array>

template<class Container, class Action>
void forEach(Container&& cont, Action&& action)
{
    auto first = std::begin(cont);
    auto last = std::end(cont);
    for( ; first != last ; ++first)
    {
        action(*first);
    }
}

int main()
{
    std::array<int, 4> num{1,2,3,4};

    forEach(num, [](auto&& n) -> void { std::cout << n * n << std::endl;});

    return 0;
}

其他用途:

#include <iostream>
#include <array>
#include <initializer_list>
#include <vector>

template<class Container, class Action>
void forEach(Container&& cont, Action&& action)
{
    auto first = std::begin(cont);
    auto last = std::end(cont);
    for( ; first != last ; ++first)
    {
        action(*first);
    }
}

int main()
{
    std::array<int, 4> num{1,2,3,4};

    // type of n is "whatever works"
    auto emit = [](auto&& n) -> void { std::cout << n * n << std::endl;};
    forEach(num, emit);

    forEach(std::array<double, 4> { 1.0, 2.0, 3.0, 4.0 }, emit);
    forEach(std::initializer_list<double>{ 1.0, 2.0, 3.0, 4.0 }, emit);
    forEach(std::vector<double>{ 1.0, 2.0, 3.0, 4.0 }, emit);

    return 0;
}

【讨论】:

  • 谢谢,它对我来说很好用。你能给我解释一下&amp;&amp;吗?这是对引用的引用吗?
  • @Morchul 意思是“通用参考”。参数的类型将被推导为X&amp;X const&amp;X&amp;&amp;中最合适的一个(r值引用)
  • 好的,我不熟悉,所以我会读一些关于它的东西。再次感谢您的帮助和链接
  • @Morchul 这可能会有所帮助。 isocpp.org/blog/2012/11/… 其起源是人们正在寻找一种方法来有效地将参数传递给泛型函数 - 而不会调用不必要的副本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-02
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 2017-10-06
  • 2019-12-13
  • 1970-01-01
相关资源
最近更新 更多