给定一个范围(可能是一个带有开始/结束迭代器成员的容器),是否有一种可靠的方法来确定其元素的类型?
以下几乎一直有效,但在普通数组上失败。
我已经看到使用该类型的建议,Container::value_type
但当然不是为内置数组定义的。
begin(int [3])
不知何故,使用 GCC 4.8.1 编译时找不到以下代码。它确实适用于 Microsoft Visual Studio 2012。
#include <iostream>
#include <vector>
// Identify the type of element in given range type.
template<typename Range> struct range_elem {
typedef typename std::decay<decltype(*std::begin(std::declval<Range>()))>::type type;
};
// Count the number of elements in range matching value.
template<typename Range>
int count(const Range& range, typename range_elem<Range>::type value) {
int n = 0;
for (const auto& e : range) { if (e==value) n++; }
return n;
}
struct S { };
int count(S&, int) { return 10; } // further test robustness to overload
int main() {
// This compiles OK.
std::vector<int> vec; vec.push_back(1); vec.push_back(2); vec.push_back(3);
std::cerr << count(vec, 2) << "\n";
//
int ar[3] = {1,2,3};
// This compiles OK.
{
int n = 0;
for (const auto& e : ar) { if (e==2) n++; }
std::cerr << n << "\n";
}
// This fails to compile on gcc 4.8.1;
// error: no matching function for call to 'begin(int [3])'
std::cerr << count(ar, 2) << "\n";
//
// Somehow realize SFINAE when overloading with a different type that does not support begin/end?
S s; std::cerr << count(s,2) << "\n";
return 0;
}