(此问题已从原版中进行了大幅度编辑,未改变原始问题的真实意图)
如果我们将vector<int>
中的所有元素相加,那么答案可能会溢出,需要intmax_t
之类的内容来准确 和存储答案而不会溢出。但intmax_t
不适合vector<double>
。
我可以手动指定类型:
template<typename>
struct sum_traits;
template<>
struct sum_traits<int> {
typedef long accumulate_safely_t;
};
然后按如下方式使用它们:
template<typename C>
auto sum(const C& c) {
sum_traits<decltype(c.begin())> :: accumulate_safely_t> r = 0;
for(auto &el: c)
r += el;
return r;
}
我的问题:是否可以自动识别合适的类型,大而准确的类型,因此我不必通过类型特征手动指定每个类型?
答案 0 :(得分:4)
您的代码的主要问题是self.view.layer.backgroundColor = [UIColor clearColor].CGColor;
等同于auto r = 0
。这不是你的C ++ 98代码的工作方式。通常,您无法找到完美的目标类型。您的代码只是int r = 0
的变体,因此我们可以看一下标准如何解决这个问题:它允许您传递累加器的初始值,还有它的类型:std::accumulate
答案 1 :(得分:3)
假设:
如果我们将向量中的所有元素相加,那么答案可能会溢出,需要像intmax_t那样准确地存储答案而不会溢出。
问题:
我的问题:是否可以自动识别合适的类型,大而准确的类型,因此我不必通过类型特征手动指定每个类型?
这里的问题是你想要获取运行时数据(向量)并从中推导出一种类型(编译时的东西)。
由于类型推导是一个编译时操作,我们必须在编译时只使用我们可用的信息来做出这个决定。
我们在编译时获得的唯一信息(除非您提供更多信息)是var sortedKeys = Array(dict.keys).sort({dict[$0] > dict[$1]})
和std::numeric_limits<int>::max()
。
在这个阶段你甚至没有std::numeric_limits<std::vector<int>::size_type>::max()
,因为它不是std::vector<int>::max_size()
的强制要求。你也不能依赖constexpr
,因为它是:
所以我们留下的是最大可能的总和:
std::vector<int>::allocator_type::max_size()
我们现在可以使用编译时析取来找到一个合适的整数(如果存在这样的整数)(涉及std::numeric_limits<int>::max() * std::numeric_limits<std::vector<int>::size_type>::max()
的内容)
这不会使类型适应运行时条件,但它至少会适应您正在编译的体系结构。
这样的事情:
std::conditional
答案 2 :(得分:1)
您可以在C ++ 14中使用return type deduction,如下所示:
template<typename C>
auto sum(const C& c) {
auto r = 0;
for(auto &el: c)
r += el;
return r;
}
在C ++ 11中,考虑到您的C ++ 98代码,您可以使用以下代码:
template<typename C>
auto sum(const C& c) -> typename C::value_type {
auto r = 0;
for(auto &el: c)
r += el;
return r;
}
但是,正如评论中所指出的,auto r = 0;
在编译时仍会解析为int
。正如在另一个答案中提出的那样,您可能希望将初始值类型(以及返回值类型)设置为模板参数:
template<typename C, typename T>
T sum(const C& c, T init) {
for(auto &el: c)
init += el;
return init;
}
// usage
std::vector<std::string> v({"Hello ", "World ", "!!!"});
std::cout << sum(v, std::string{});