如何默认构造迭代器的 value_type 作为函数中的默认参数?
How to default construct value_type of iterator as default argument in the function?
这里是可憎之处:
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<>{})
所以我希望 T
默认为 std::iterator_traits<BidirIt>::value_type
并且默认构造一个该类型的对象并为其命名 init
.
在解决了在一行中拟合某些变量类型的问题后,我发现编译器无法推导T
,这就是它的确切含义:
error: no matching function for call to 'sliding_window'
sliding_window(v.begin(), v.end(), output.begin(), window_length/, 0, std::plus<>(), std::minus<>()/);
note: candidate template ignored: couldn't infer template argument 'T'
void sliding_window(BidirIt first, BidirIt last, OutputIt d_first,
我的编译器是clang++-3.9.
调用站点代码:
std::vector<int> v(window_length + window_count - 1);
std::iota(v.begin(), v.end(), 0);
std::vector<int> output(window_count);
std::vector<int> correct_result{3, 6, 9, 12};
sliding_window(v.begin(), v.end(), output.begin(), window_length/*, 0, std::plus<>(), std::minus<>()*/);
当注释部分未注释时,代码可以正常工作。
根据我对模板的了解,它应该能够推断出该类型,因为它实际上是那里的默认构造函数调用,它应该产生 std::iterator_traits<BidirIt>::value_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 = {})
模板类型不是从默认值推导出来的。
所以你必须手动设置默认类型。
无法从默认的模板化参数中推导出模板类型:。至于如何修复它,您需要默认类型:
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{})
另一种方法也是重载函数,其中模板较少的函数 parameters/arguments 调用模板较多的函数并在调用站点处理默认设置。这是 std::accumulate
: http://en.cppreference.com/w/cpp/algorithm/accumulate 使用的方法。然后你会有多个函数,所以那里有一些重复,但每个函数都更具可读性。
这里是可憎之处:
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<>{})
所以我希望 T
默认为 std::iterator_traits<BidirIt>::value_type
并且默认构造一个该类型的对象并为其命名 init
.
在解决了在一行中拟合某些变量类型的问题后,我发现编译器无法推导T
,这就是它的确切含义:
error: no matching function for call to 'sliding_window' sliding_window(v.begin(), v.end(), output.begin(), window_length/, 0, std::plus<>(), std::minus<>()/);
note: candidate template ignored: couldn't infer template argument 'T' void sliding_window(BidirIt first, BidirIt last, OutputIt d_first,
我的编译器是clang++-3.9.
调用站点代码:
std::vector<int> v(window_length + window_count - 1);
std::iota(v.begin(), v.end(), 0);
std::vector<int> output(window_count);
std::vector<int> correct_result{3, 6, 9, 12};
sliding_window(v.begin(), v.end(), output.begin(), window_length/*, 0, std::plus<>(), std::minus<>()*/);
当注释部分未注释时,代码可以正常工作。
根据我对模板的了解,它应该能够推断出该类型,因为它实际上是那里的默认构造函数调用,它应该产生 std::iterator_traits<BidirIt>::value_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 = {})
模板类型不是从默认值推导出来的。 所以你必须手动设置默认类型。
无法从默认的模板化参数中推导出模板类型:
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{})
另一种方法也是重载函数,其中模板较少的函数 parameters/arguments 调用模板较多的函数并在调用站点处理默认设置。这是 std::accumulate
: http://en.cppreference.com/w/cpp/algorithm/accumulate 使用的方法。然后你会有多个函数,所以那里有一些重复,但每个函数都更具可读性。