C++ 使用lambda和全局函数调用范围::for_

C++ 使用lambda和全局函数调用范围::for_,c++,c++11,c++14,range-v3,C++,C++11,C++14,Range V3,以下代码按预期工作: void foo(auto const &){} auto const rng{ranges::view::all(v)}; ranges::for_each(rng, [](auto const & r){ foo(r); }); 但以下几点: void foo(auto const &){} auto const rng{ranges::view::all(v)}; ranges::for_each(rng, &foo);

以下代码按预期工作:

void foo(auto const &){}

auto const rng{ranges::view::all(v)};
ranges::for_each(rng, [](auto const & r){
    foo(r);
});
但以下几点:

void foo(auto const &){}

auto const rng{ranges::view::all(v)};
ranges::for_each(rng, &foo);
给出编译错误:

template argument deduction/substitution failed:
couldn't deduce template parameter 'F'

我查看了,但老实说,我无法理解问题所在。

如果不明确指定所需的重载/实例化,就无法获取重载或模板函数的地址

在第一个代码段中传递lambda表达式是解决此问题的好方法

或者,如果您有权访问
foo
,则可以将其转换为函数对象:


如果不明确指定所需的重载/实例化,则无法通过获取重载或模板函数的地址

在第一个代码段中传递lambda表达式是解决此问题的好方法

或者,如果您有权访问
foo
,则可以将其转换为函数对象:


函数名不代表函数;它是函数名的重载集

你的职能

void foo(auto const &){}
似乎正在使用该语言的概念式扩展来实现简洁的模板函数。在标准C++中,它会读取:

template<class T>
void foo(T const &){}
它构建了一个表示全局函数名重载的无状态lambda

因此:

如果您希望捕获较少的拐角案例,请执行以下简单操作:

void foo(auto const &){}

auto const rng{ranges::view::all(v)};
ranges::for_each(rng, [](auto&x){foo(x);});
在这种特定情况下也有效


另一方面,有一个C++20建议将(foo)的
重载替换为
[](自动和…args)=>foo(decltype(args)(args)
(产生与宏相同的效果)。遗憾的是,
decltype
noexcept
功能被否决。

函数名并不代表函数;它是函数名的重载集

你的职能

void foo(auto const &){}
似乎正在使用该语言的概念式扩展来实现简洁的模板函数。在标准C++中,它会读取:

template<class T>
void foo(T const &){}
它构建了一个表示全局函数名重载的无状态lambda

因此:

如果您希望捕获较少的拐角案例,请执行以下简单操作:

void foo(auto const &){}

auto const rng{ranges::view::all(v)};
ranges::for_each(rng, [](auto&x){foo(x);});
在这种特定情况下也有效


另一方面,有一个C++20建议将(foo)
重载替换为
[](自动和…args)=>foo(decltype(args)(args)
(产生与宏相同的效果)。可悲的是,
decltype
noexcept
的特点是投票被否决。

Oh。该函数的参数类型为
auto
。那完全出乎我的意料。因此,我的问题与
范围v3
无关。谢谢哦该函数的参数类型为
auto
。那完全出乎我的意料。因此,我的问题与
范围v3
无关。谢谢“遗憾的是,
decltype
noexcept
功能被否决。”太快了:(谢谢。
#定义(…)的重载。
看起来很吓人-宏加上前向引用变量auto.o_O@nikitablack注意,
[](auto&x){foo(x);}
解决了您在这个特定案例中的问题;
重载
只解决了几乎所有我们可以在一个地点解决的角落案例。我不会说它被“否决”。我当时的印象是我必须带着一份更好的论文回来(顺便说一句,我的提案)。我真正想要的是像
[](args…=>foo(>>args…)
,但它仍然需要大量的工作,我们会看看会发生什么。@Barry I dunno。必须命名
args
两次。那么
[]=>foo(>@…
)呢,其中
@
自动和…
参数的隐式参数包。(我是孩子)“遗憾的是,
decltype
noexcept
功能被否决。”太快了。:(谢谢。
#定义(…)
的重载看起来很可怕-宏加上前向引用的变量自动。o_O@nikitablack注意,
[](auto&x){foo(x);}
解决了您在这个特定案例中的问题;
重载
只解决了几乎所有我们可以在一个地点解决的角落案例。我不会说它被“否决”。我当时的印象是我必须带着一份更好的论文回来(顺便说一句,我的提案)。我真正想要的是像
[](args…=>foo(>>args…)
,但它仍然需要大量的工作,我们会看看会发生什么。@Barry I dunno。必须命名
args
两次。那么
[]=>foo(>@…
)呢,其中
@
自动和…
参数的隐式参数包。(我是孩子)
void foo(auto const &){}

auto const rng{ranges::view::all(v)};
ranges::for_each(rng, [](auto&x){foo(x);});