如果从lambda内部调用,则无法实例化使用decltype推导返回类型的函数模板?

jal*_*alf 9 c++ lambda decltype visual-c++-2010 c++11

我正在尝试使用C++ 0x,特别是lambda表达式和decltype来简化我的一些代码,使用MSVC10 RC编译器.

我遇到了以下非常奇怪的问题:

template <typename F>
auto foo(F f) -> decltype(f()){
  return f();
}

template <typename F>
void bar(F f){
  f();
}

int main() {
  bar([](){
    foo([]() { }); // error C2893: Failed to specialize function template ''unknown-type' foo(F)'
  });
}
Run Code Online (Sandbox Code Playgroud)

如注释中所示,编译器在该行上生成错误foo([]() { }).

我讨厌大喊"编译器错误",但我真的看不出任何有关此错误的好解释.显然,在外部lambda表达式中,编译器不能专门化foo内部lambda 的 函数模板.

但是,如果将定义foo更改为硬编码返回类型,如下所示:

template <typename F>
void foo(F f){
  return f();
}
Run Code Online (Sandbox Code Playgroud)

然后一切都编好了.

当用于推断另一个我不知道的lambda范围内的lambda表达式参数的返回类型时,是否有一些模糊的decltype怪癖?

GMa*_*ckG 3

这些只是一些供人们观察的测试用例。

作品

template <typename F>
auto foo(F f) -> decltype(f())
{
  return f();
}

void dummy() {}

int main()
{
    auto x = []()
            {   // non-lambda parameter
                foo(dummy);
            };
}
Run Code Online (Sandbox Code Playgroud)
template <typename F>
auto foo(F f) -> decltype(f())
{
  return f();
}

int main()
{
    auto f = [](){};
    auto x = [&]()
            {    // pre-defined lambda
                foo(f);
            };
}
Run Code Online (Sandbox Code Playgroud)

失败

template <typename F>
auto foo(F f) -> decltype(f())
{
  return f();
}

int main()
{
    auto x = []()
            {   // in-argument lambda
                foo([]{});
            };
}
Run Code Online (Sandbox Code Playgroud)
template <typename F>
auto foo(F f) -> decltype(f())
{
  return f();
}

int main()
{
    auto x = []()
            {   // in-scope lambda
                auto f = []{};
                foo(f);
            };
}
Run Code Online (Sandbox Code Playgroud)
template <typename F>
auto foo(F f) -> decltype(f())
{
  return f();
}

int main()
{
    auto x = []()
            {   // in-scope lambda, explicit return
                // (explicit return type fails too, `-> void`)
                auto f = [](){ return; };
                foo(f);
            };
}
Run Code Online (Sandbox Code Playgroud)
template <typename F>
auto foo(F f) -> decltype(f())
{
  return f();
}

int main()
{
    auto x = []()
            {   // in-argument lambda, explicit return non-void
                // (explicit return type fails too, `-> int`)
                foo([]{ return 5; }); 
            };
}
Run Code Online (Sandbox Code Playgroud)

所以它似乎确实与内部 lambda 的范围void类型有关,即使是显式的也是如此。(?)