典型的功能模板签名:
template<typename Iterator, typename T>
T fn(Iterator first, Iterator last, T init)
{
T result;
// ...
return result;
}
问题是,当我这样称呼时:
std::vector<long> data(1000,1);
fn(data.begin(), data.end(), 0);
或未明确调用的任何其他方式
fn<std::vector<long>::iterator, long>(data.begin(), data.end(),0);
然后T的类型是int
,fn
存在溢出和不良结果的风险。
那么我如何专门化fn
以便调用
fn(data.begin(), data.end(), 0);
是否明确无误,导致T
设置为Iterator::value_type
?选择
template<Iterator>
typename iterator_traits<Iterator>::value_type fn(Iterator first, Iterator last, typename iterator_traits<Iterator>::value_type init)
{
//...
}
导致g ++ / clang ++出现模糊的调用错误。
编辑:
我现在看到了我的错误,上面的代码适用于@Lightness Races建议。谢谢你的帮助。
答案 0 :(得分:2)
为什么不简单地传递一下?
fn(data.begin(), data.end(), 0L);
除此之外你可能会做这样的事情:
#include <type_traits>
template<typename Iterator>
typename std::iterator_traits<Iterator>::value_type fn(
Iterator first,
Iterator last,
typename std::iterator_traits<Iterator>::value_type init
);
答案 1 :(得分:1)
如:
0 is an int
0L is a long
您只需使用正确的参数调用该方法:
为:
fn(data.begin(), data.end(), 0L);
为:
long init = 0; // result in 0L
fn(data.begin(), data.end(), init);
as:
fn(data.begin(), data.end(), static_cast<long>(0));
编写fn
以避免正确调用它的一种方法是
template<typename Iterator>
auto fn(Iterator first, Iterator last, typename std::decay<decltype(*first)>::type init)
-> typename std::decay<decltype(*first)>::type;