C++ 如何默认构造迭代器的值\类型作为函数中的默认参数?

C++ 如何默认构造迭代器的值\类型作为函数中的默认参数?,c++,templates,iterator,c++14,default-constructor,C++,Templates,Iterator,C++14,Default Constructor,这是令人憎恶的: template <typename BidirIt, typename OutputIt, typename T, typename BinaryDoOp, typename BinaryUndoOp> void sliding_window(BidirIt first, BidirIt last, OutputIt d_first, typename std::iterator_traits<Bi

这是令人憎恶的:

template <typename BidirIt, typename OutputIt, typename T,
          typename BinaryDoOp, typename BinaryUndoOp>
void sliding_window(BidirIt first, BidirIt last, OutputIt d_first,
                    typename std::iterator_traits<BidirIt>::difference_type length,
                    T init = typename std::iterator_traits<BidirIt>::value_type(),
                    BinaryDoOp op = std::plus<>{},
                    BinaryUndoOp undo = std::minus<>{})
当注释部分未注释时,代码正常工作

根据我对模板的了解,它应该能够推断出该类型,因为它实际上是一个默认的构造函数调用,应该会产生
std::iterator\u traits::value\u type
。当函数模板化在一个类型上时,我是否对默认参数的类型有任何误解

问题:如何修复?如果能给它添加一些解释,那就太好了。

应该是:

template <typename BidirIt,
          typename OutputIt,
          typename T = typename std::iterator_traits<BidirIt>::value_type,
          typename BinaryDoOp = std::plus<>,
          typename BinaryUndoOp = std::minus<>>
void sliding_window(BidirIt first,
                    BidirIt last,
                    OutputIt d_first,
                    typename std::iterator_traits<BidirIt>::difference_type length,
                    T init = {},
                    BinaryDoOp op = {},
                    BinaryUndoOp undo = {})
模板
无效滑动窗口(首先为BidirIt,
最后,
首先输出d_,
typename std::迭代器特征::差异类型长度,
T init={},
二进制doop={},
BinaryUndop撤消={})
模板类型不是从默认值推导出来的。 因此,您必须手动设置默认类型。

它应该是:

template <typename BidirIt,
          typename OutputIt,
          typename T = typename std::iterator_traits<BidirIt>::value_type,
          typename BinaryDoOp = std::plus<>,
          typename BinaryUndoOp = std::minus<>>
void sliding_window(BidirIt first,
                    BidirIt last,
                    OutputIt d_first,
                    typename std::iterator_traits<BidirIt>::difference_type length,
                    T init = {},
                    BinaryDoOp op = {},
                    BinaryUndoOp undo = {})
模板
无效滑动窗口(首先为BidirIt,
最后,
首先输出d_,
typename std::迭代器特征::差异类型长度,
T init={},
二进制doop={},
BinaryUndop撤消={})
模板类型不是从默认值推导出来的。
因此,您必须手动设置默认类型。

无法从默认模板参数推断模板类型:。至于如何修复,您需要默认类型:

template <typename BidirIt, typename OutputIt,
    typename T = typename std::iterator_traits<BiDirIt>::value_type,
    typename BinaryDoOp = std::plus<>,
    typename BinaryUndoOp = std::minus<>>
void sliding_window(BidirIt first, BidirIt last, OutputIt d_first,
                typename std::iterator_traits<BidirIt>::difference_type length,
                T init = T{},
                BinaryDoOp op = BinaryDoOp{},
                BinaryUndoOp undo = BinaryUndoOp{})
模板
无效滑动窗口(BidirIt first,BidirIt last,outpuit d_first,
typename std::迭代器特征::差异类型长度,
T init=T{},
BinaryDoOp op=BinaryDoOp{},
BinaryUndop undo=BinaryUndop{})

另一种方法是使用重载函数,其中具有较少模板参数/参数的函数调用具有较多模板参数/参数的函数,并在调用站点处理缺省值。这是
std::acculate
使用的方法。然后您将有多个函数,因此其中会有一些重复,但每个函数的可读性都会更好。

模板类型不能从默认的模板参数推断:。至于如何修复,您需要默认类型:

template <typename BidirIt, typename OutputIt,
    typename T = typename std::iterator_traits<BiDirIt>::value_type,
    typename BinaryDoOp = std::plus<>,
    typename BinaryUndoOp = std::minus<>>
void sliding_window(BidirIt first, BidirIt last, OutputIt d_first,
                typename std::iterator_traits<BidirIt>::difference_type length,
                T init = T{},
                BinaryDoOp op = BinaryDoOp{},
                BinaryUndoOp undo = BinaryUndoOp{})
模板
无效滑动窗口(BidirIt first,BidirIt last,outpuit d_first,
typename std::迭代器特征::差异类型长度,
T init=T{},
BinaryDoOp op=BinaryDoOp{},
BinaryUndop undo=BinaryUndop{})

另一种方法是使用重载函数,其中具有较少模板参数/参数的函数调用具有较多模板参数/参数的函数,并在调用站点处理缺省值。这是
std::acculate
使用的方法。然后,您将有多个函数,因此其中会有一些重复,但每个函数的可读性都会更好。

谢谢,它可以工作。对未来的读者来说,解释是很好的,但从表面上看,它们似乎很明显是有用的。对未来的读者来说,解释是很好的,但从表面上看,它们显然需要更多的信息。Jarod的版本编译正确,我相信它符合标准,所以在=的rhs上省略类型是个好主意吗?不同的重载可以相互委托,所以重复应该不是问题。除非你说的是界面本身…谢谢你提供更多信息。Jarod的版本编译正确,我相信它符合标准,所以在=的rhs上省略类型是个好主意吗?不同的重载可以相互委托,所以重复应该不是问题。除非你说的是界面本身。。。