Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板类型推导中的隐式转换_C++_Templates_Iterator_Type Conversion - Fatal编程技术网

C++ 模板类型推导中的隐式转换

C++ 模板类型推导中的隐式转换,c++,templates,iterator,type-conversion,C++,Templates,Iterator,Type Conversion,在这种情况下,OP询问为什么他的std::accumulate函数返回错误的值。答案是因为他传入了一个int作为初始值,因此使计算都是int而不是double。我有两个版本: template <class InputIterator, class T> auto accumulate (InputIterator first, InputIterator last, T init) { typedef typename std::iterator_traits<Input

在这种情况下,OP询问为什么他的std::accumulate函数返回错误的值。答案是因为他传入了一个int作为初始值,因此使计算都是int而不是double。我有两个版本:

template <class InputIterator, class T>
auto accumulate (InputIterator first, InputIterator last, T init)
{
  typedef typename std::iterator_traits<InputIterator>::value_type vt;
  vt init2 = vt(init);
  // ...
  return init2;
}

template <class InputIterator, class T = typename std::iterator_traits<InputIterator>::value_type>
T not_working (InputIterator first, InputIterator last, T init)
{
// ...
return init;
}
为什么在版本2中T仍然是int?因为隐式转换

T仍在推导中,将覆盖默认参数:

你想要这个:

template <class InputIterator>
typename std::iterator_traits<InputIterator>::value_type
working(InputIterator first, InputIterator last,
        typename std::iterator_traits<InputIterator>::value_type init) {
    return init;
}
T仍在推导中,将覆盖默认参数:

你想要这个:

template <class InputIterator>
typename std::iterator_traits<InputIterator>::value_type
working(InputIterator first, InputIterator last,
        typename std::iterator_traits<InputIterator>::value_type init) {
    return init;
}

直接问题的答案已经说明:如果类型可以从参数列表中推断,那么它将被推断。将使用的类型设为嵌套类型可防止对其进行推断:

template <typename T>
struct identity {
    typedef T type;
};
template <typename It, typename T = typename std::iterator_traits<It>::value_type>
T safe_accumulate(It begin, It end, typename identity<T>::type sum) {
    return std::accumulate(begin, end, sum);
}
可以通过将结果类型放在第一位的方式实现:

template <typename T = void, typename It>
typename std::conditional<std::is_same<T, void>::value,
    typename std::iterator_traits<It>::value_type,
    T>::type
safe_accumulate(It begin, It end,
                typename std::conditional<std::is_same<T, void>::value,
                    typename std::iterator_traits<It>::value_type,
                    T>::type sum) {
    return std::accumulate(begin, end, sum);
}
现在该算法可以以更方便的方式使用,即该算法的实现者为了用户的利益提供了更复杂的实现:

std::cout << safe_accumulate<long>(s.begin(), s.end(), 0) << '\n';

直接问题的答案已经说明:如果类型可以从参数列表中推断,那么它将被推断。将使用的类型设为嵌套类型可防止对其进行推断:

template <typename T>
struct identity {
    typedef T type;
};
template <typename It, typename T = typename std::iterator_traits<It>::value_type>
T safe_accumulate(It begin, It end, typename identity<T>::type sum) {
    return std::accumulate(begin, end, sum);
}
可以通过将结果类型放在第一位的方式实现:

template <typename T = void, typename It>
typename std::conditional<std::is_same<T, void>::value,
    typename std::iterator_traits<It>::value_type,
    T>::type
safe_accumulate(It begin, It end,
                typename std::conditional<std::is_same<T, void>::value,
                    typename std::iterator_traits<It>::value_type,
                    T>::type sum) {
    return std::accumulate(begin, end, sum);
}
现在该算法可以以更方便的方式使用,即该算法的实现者为了用户的利益提供了更复杂的实现:

std::cout << safe_accumulate<long>(s.begin(), s.end(), 0) << '\n';