【发布时间】:2017-05-22 12:35:19
【问题描述】:
下一个代码 sn-p 展示了如何简化用户代码,使库稍微复杂一些。换句话说,添加一些语法糖。
Channel const& joinMulticast(NetAdres const &group) const;
/// Auto-construct NetAdres.
/// joinMulticast() can take any combination of args and passes them to NetAdres::NetAdres() constructor. No need to write many overloads
template<typename... Y>
auto joinMulticast(Y&&... y)
-> decltype(joinMulticast(std::declval<Y>()...))
{
return joinMulticast(NetAdres(std::forward<Y>(y)...));
}
VS2015 默默吃东西,但 GCC 无法消化这段代码并出现致命错误:
template instantiation depth exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum)
-> decltype(joinMulticast(std::declval<Y>()...))
~~~~~~~~~~~~~~~^~
【问题讨论】:
-
你的声明没有任何意义。它本质上是
auto f() -> decltype(f());- 它试图声明一个函数,其返回类型是该函数将返回的类型;循环推理。您的意思是decltype(joinMulticast(NetAdres(std::forward<Y>(std::declval<Y>())...)))吗?至于为什么 MSVC 接受它——我预测如果你尝试真正调用这个野兽,你会得到一个错误。众所周知,MSVC 没有实现模板的两阶段翻译,将所有语义检查推迟到实例化点。 -
@IgorTandetnik 即使这样还不够,因为第二个重载仍然优于第一个。
-
@IgorTandetnik,这没有帮助。同样的错误。
标签: c++11 gcc visual-c++ c++14 syntactic-sugar