`ocutor<<`在容器上适用于价值和参考
有一个模板的容器类容器
,因此可以包含任何内容。
我想增加将其内容打印到std :: Ostream
的能力,因此我已经Overriden 操作员<<
。
但是,这有一个缺点:如果容器包含引用(或指针),则该方法仅打印地址而不是真实信息。
请考虑此简单的测试代码,该代码证明了问题:
#include <iostream>
#include <deque>
template<typename T, bool is_reference = false>
class container {
public:
container() {}
void add(T a) { queue.push_back(a); }
friend std::ostream& operator<<(std::ostream& out, const container<T, is_reference>& c) {
for (const T& item : c.queue) {
if (is_reference) out << *item; else out << item;
out << ",";
}
return out;
}
private:
std::deque<T> queue;
};
int main() {
//Containers
container<int*, true> myContainer1;
container<int> myContainer2;
int myA1(1);
int myA2(10);
myContainer1.add(&myA1);
myContainer1.add(&myA2);
myContainer2.add(myA1);
myContainer2.add(myA2);
std::cout << myA1 << std::endl;
std::cout << myA2 << std::endl;
std::cout << myContainer1 << std::endl;
std::cout << myContainer2 << std::endl;
return 0;
}
我有一个想法在模板中提供额外的is_Reference
布尔值,以调整ocerator&lt;&lt;&lt;
。
但是,如果我具有 value type 容器,这会导致早期编译器错误。
我该如何完成这项工作?
如果我将打印机行更改为
out << item << ",";
“代码”编译并打印以下内容:
1
10
0x7ffd77357a90,0x7ffd77357a94,
1,10,
显然我的目标是获得此结果:
1
10
1,10,
1,10,
((如何)我可以轻松实现此目标?
There is a container class container
which is templated, so it can contain anything.
I want to add ability to print its contents to std::ostream
so I've overriden operator<<
.
However this has a drawback: if the container contains references (or pointers), the method only prints addresses instead of real information.
Please consider this simple test code which demonstrates the problem:
#include <iostream>
#include <deque>
template<typename T, bool is_reference = false>
class container {
public:
container() {}
void add(T a) { queue.push_back(a); }
friend std::ostream& operator<<(std::ostream& out, const container<T, is_reference>& c) {
for (const T& item : c.queue) {
if (is_reference) out << *item; else out << item;
out << ",";
}
return out;
}
private:
std::deque<T> queue;
};
int main() {
//Containers
container<int*, true> myContainer1;
container<int> myContainer2;
int myA1(1);
int myA2(10);
myContainer1.add(&myA1);
myContainer1.add(&myA2);
myContainer2.add(myA1);
myContainer2.add(myA2);
std::cout << myA1 << std::endl;
std::cout << myA2 << std::endl;
std::cout << myContainer1 << std::endl;
std::cout << myContainer2 << std::endl;
return 0;
}
I had an idea to provide an extra is_reference
boolean in the template for adjusting the operator<<
.
However this causes an early compiler error, in case I have value type container(s).
How can I make this work?
If I change the printer line to
out << item << ",";
The code compiles and prints this:
1
10
0x7ffd77357a90,0x7ffd77357a94,
1,10,
Obviously my goal is to have this result:
1
10
1,10,
1,10,
(How) can I achieve this easily?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用Sfinae根据
std :: is_pointer&lt; t&gt; :: value
is true 或false
。这已经与C ++ 11:output :
由于C ++ 17您可以使用
>
> constexpr如果
。另外,由于C ++ 17有std :: IS_POInter_V
,并且由于C ++ 14有std :: Enable_if_t
,因此两者都会使代码少一些。You can use SFINAE to select an overload based on whether
std::is_pointer<T>::value
istrue
orfalse
. This works already with C++11:Output:
Since C++17 you can use
constexpr if
. Also since C++17 there isstd::is_pointer_v
and since C++14 there isstd::enable_if_t
, both would make the code a little less verbose.对于
item
和*item
工作的条件选择,您将需要一个支持C ++ 17标准(或更高版本)的编译器,然后使用>如果constexpr(...)
语句。另外,您可以使用
std :: is_pointer
检查包含的类型是否是指针,而不是在模板中添加“标志”:For the conditional choice between
item
and*item
to work, you will need a compiler that supports the C++17 Standard (or later) and then use anif constexpr (...)
statement.Also, you can use
std::is_pointer
to check whether the contained type is a pointer, rather than adding a 'flag' to your template: