如果从lambda内部调用,则无法实例化使用dectType推断返回类型的函数模板?
-
22-09-2019 - |
题
我正在尝试使用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
不隶属于 StackOverflow