最近,我对现代c++进行了研究。我在[49:00]看到了有关c++ 11/c++ 14可变参数模板的video。如果要使用可变参量模板计算不同类型(例如int
,double
)的元组的总和,请使用c++ 11,该视频提供了一种解决方案:
struct Sum
{
template<typename T>
static T sum(T n)
{
return n;
}
template<typename T, typename... Args>
static auto sum(T n, Args... rest) -> decltype(n+sum(rest...))
{
return n + sum(rest...);
}
}
auto x = Sum::sum(1, 2.5, 3);
auto
无法推断出c++11
中的返回类型,因此您必须使用decltype
声明返回类型。但是某些编译器构建失败,某些编译器构建成功。 link尽管使用
auto to deduce return type
没问题,但我的问题是:c++11
标准涵盖了这个问题吗?如果不是,那么编译器是否通过自己的实现来解决问题? gcc 8.1
编译失败,而gcc 4/5/6/7
编译成功? gcc是否存在任何兼容性问题? 顺便说一句,编译错误消息是:
最佳答案
此处以尾随返回类型查找功能名称,
template<typename T, typename... Args>
static auto sum(T n, Args... rest) -> decltype(n+sum(rest...))
在声明此
sum
之前的上下文中完成,以及通过ADL(依赖于参数的查找)完成。而且,由于在有关类型的调用点无法通过ADL看到此模板,因此该模板无法编译是适当的。
较早的gcc编译器可能除了应该使用的上下文之外,还使用对象上下文。这是一个合理的错误。
您可以轻松解决此问题:
struct Sum {
private:
template<typename T>
friend T summer(Sum, T n) {
return n;
}
template<typename T, typename... Args>
friend auto summer(Sum, T n, Args... rest) -> decltype(n+summer(Sum{},rest...)) {
return n + summer(Sum{},rest...);
}
public:
template<class...Args>
auto sum(Args...args)->decltype(summer(Sum{}, args...)){
return summer(Sum{}, args... );
}
};
在这里,我们在一些私有(private) friend 中强制使用ADL。这允许夏季的重载以其尾随的返回类型“看到自己”。
关于c++ - 使用c++ 11的不同输入类型的C++可变参数模板,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50206610/