gpt4 book ai didi

c++ - 如何键入用于 const 对象的自定义 io 操纵器?

转载 作者:行者123 更新时间:2023-11-30 04:58:55 25 4
gpt4 key购买 nike

我正在尝试提升我编写的一个简单的 Array-io 操纵器以使用 std::vector秒。这是我一直在使用的旧签名:

template<typename T>
struct arr {
const size_t size;
T* values;
arr(const size_t size, T* values) : size(size), values(values) {};

friend std::ostream& operator<<(std::ostream& os, const arr<T>& array);

friend std::istream& operator>>(std::istream& is, arr<T>& array);
};

现在我试着像这样抬起它:

template<typename T>
struct arr {
std::vector<T>& vec;
arr(std::vector<T>& vec) : vec(vec) {};

friend std::ostream& operator<<(std::ostream& os, const arr<T>& array);

friend std::istream& operator>>(std::istream& is, arr<T>& array);
};

但是我面临以下问题:我想使用 << arr(member)从内部 const声明的成员方法。这当然不能编译:

error: binding reference of type ‘std::vector<std::unique_ptr<IController> >&’ to ‘const std::vector<std::unique_ptr<IController> >’ discards qualifiers

但是,当我更改构造函数参数和 arr::vec 时至 const std::vector<T>&我有相反的问题和>> arr(member)不能再工作了!

我希望通过初始化 arr实例为 const我可以解决这个问题,但我遇到了以下行的相同编译器错误:

const streamutils::arr<int> list(myVector);

如何在不为进出方向声明两种不同类型的情况下解决这个问题?我试图查看 libstdc++ 源代码以了解它是如何为 std::quoted 完成的但我想不通。

最佳答案

您可以不使用 T 参数化您的操纵器但是用vector<T>本身。这样你就不用担心你的 vector 是不是 const 了。同时创建一个辅助函数,它返回具有相应模板类型的类的实例。

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帖子,它解释了结交模板运算符的各种方法(我在这里展示的不是最好的,也不是唯一可能的)。

关于c++ - 如何键入用于 const 对象的自定义 io 操纵器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51477793/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com