由于无限的编译时递归,以下代码的编译存在问题。 Clang 3.6.0给出了关于递归模板实例化深度的错误,并且没有终止;虽然GCC 4.9.2保持沉默,但也没有终止。
这是一个比我最初面对的更简单的例子,当然bar
的第二次重载可以作为返回类型给出int
;在这种情况下,选择第一个重载来调用bar
中的main
;正如我原本希望的那样。为什么decltype
的应用程序无法解析为第一个重载,专门用于Foo
?
Foo
的第二个(默认)模板参数似乎隐藏了有关递归问题的更详细消息。这在原始语境中很有用。
template <typename T, typename A = T>
struct Foo {};
template <typename T, typename A>
int bar(const Foo<T,A> &x) { return 0; }
template <typename T>
auto bar(const T &x)
-> decltype(bar(Foo<T>{})){
return bar(Foo<T>{});
}
int main(int argc, char *argv[])
{
Foo<char> f;
bar(f);
return 0;
}
答案 0 :(得分:4)
这会失败,因为decltype
表达式需要为这些参数计算出bar
的返回类型,因此需要实例化所有bar
模板,这涉及查看{ {1}}表达式需要为这些参数计算出decltype
的返回类型,因此它需要实例化所有bar
模板...我相信你可以想象这最终如何导致让编译器崩溃。
在C ++ 14中,我们可以省略尾随返回类型以避免所有这些工作。在C ++ 11中,我们可以在bar
为T
:
Foo