可以参数化操纵器,而不是
T
但是有
vector<T>
本身。这样你就不必为向量的常量而烦恼了。还创建一个助手函数,该函数用相应的模板类型返回类的实例。
template<typename T>
using is_vector = std::is_same<T, std::vector<typename T::value_type, typename T::allocator_type>>;
template<typename T>
struct Arr {
static_assert(is_vector<std::decay_t<T>>::value);
T& vec;
// Note that arr is passed by value here because it is a temporary
// in expressions like 'cin >> arr(a)'
template<typename U>
friend std::enable_if_t<!std::is_const_v<U>, std::istream&> operator>>(std::istream& in, Arr<U> Arr);
template<typename U>
friend std::ostream& operator<<(std::ostream& out, const Arr<U>& Arr);
};
template<typename T>
std::enable_if_t<!std::is_const_v<T>, std::istream&> operator>>(std::istream& in, Arr<T> arr) {
int n;
in >> n;
arr.vec.resize(n);
for (int i = 0; i < n; ++i) {
in >> arr.vec[i];
}
return in;
}
template<typename T>
std::ostream& operator<<(std::ostream& out, const Arr<T>& arr) {
out << arr.vec.size() << "\n";
for (const auto& x: arr.vec) {
out << x << " ";
}
out << "\n";
return out;
}
template<typename T, typename = typename is_vector<std::decay_t<T>>::type>
Arr<T> arr(T& t)
{
return Arr<T>{t};
}
int main() {
vector<int> a;
cin >> arr(a);
cout << arr(a) << endl;
const vector<int> b{1, 2, 3};
cin >> arr(b); // compile error
cout << arr(b) << endl;
}
另外,考虑阅读
this
post,它解释了各种让朋友成为模板操作员的方法(我在这里展示的不是最好的,也不是唯一可能的)。