我正在尝试使用C ++ 0x,特别是Lambda表达式和声明类型来简化我的某些代码,使用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)'
  });
}

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

我讨厌喊“编译器错误”,但我真的看不到这个错误的任何很好的解释。显然,在外部lambda表达式中,编译器无法专业 foo 内部lambda的功能模板。

但是,如果定义 foo 已更改为硬码返回类型,例如:

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

然后一切都很好。

当用来推断我不知道的另一个lambda范围内的lambda表达参数的返回类型时,是否有一些晦涩的声明类型?

有帮助吗?

解决方案

这些只是人们可以观察的一些测试案例。

作品

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

void dummy() {}

int main()
{
    auto x = []()
            {   // non-lambda parameter
                foo(dummy);
            };
}

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

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

失败

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

int main()
{
    auto x = []()
            {   // in-argument lambda
                foo([]{});
            };
}

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

int main()
{
    auto x = []()
            {   // in-scope lambda
                auto f = []{};
                foo(f);
            };
}

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);
            };
}

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; }); 
            };
}

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

其他提示

“自动”的性质允许编译器计算类型。但是您的第一个示例是互相包含递归引用,因此要计算FOO的自动,您需要栏并创建bar的实例,您需要foo。

另一方面,第二个示例明确地告诉编译器:“它应该是功能的指针,所以要冷静一段时间”。由于指向功能的指针是计算出良好的类型编译器,因此知道将保留什么。只是为了模拟:比较成员的前瞻性声明

struct A; //forward
...
A a1; //this is an error
A *a2; //this is correct since pointer calculated in bytes
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top