模板类型推断中的隐式转换
Implicit conversion in template type deduction
在这个问题中,OP询问为什么他的std::accumulate
函数返回错误的值。答案是因为他传入了初始值的int
,因此计算全部int
s而不是 double
s。我有两个版本:
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;
}
直接问题的答案已经说明:如果可以从参数列表中推断出类型,则将其推导出来。将使用的类型设置为嵌套类型可防止推导它:
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);
}
但是,在某些情况下,最好指定算法的结果类型。例如,如果要对冗长字符串中的char
值求和。使用上面定义的safe_accumulate()
会使指定结果类型有点痛苦:
std::string s("hello, world");
std::cout << safe_accumulate<std::string::iterator, long>(s.begin(), s.end(), 0) << 'n';
可以实现将结果类型放在首位的方式完成:
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';
相关文章:
- 无法转换类型 C++
- 包含可变参数包的第一个可转换类型的别名的结构
- 将 std::conditional 与不可转换类型(原始与指针)一起使用
- 链接方法时出现转换类型错误
- 如何避免隐式转换类型
- 在多重继承场景中动态强制转换类型
- 编译器不支持的转换类型
- 错误调用功能无法转换类型
- 我想看到一个在整个后缀表达式的上下文中查找转换类型 id 的示例
- 对于动态类型为强制转换类型的对象,dynamic_cast失败
- 无法在初始化中转换类型
- 如何让"auto"转换类型
- 如何通过强制转换类型指针将字符数组转换为uint16_t
- 如何从新运算符+(Template类)返回具有转换类型的对象
- 带有模板的基于枚举的工厂无法转换类型
- 使用SWIG类型映射通过字符串转换类型
- 对于可转换类型,设计比循环依赖项更好
- SWIG不能正确转换类型定义
- 将类型转换扩展到可转换类型的对/元组
- 想要将字符数组的部分转换/类型转换为值