C++ 将PrintContainer预处理器定义转换为C+中的模板+;11
我已经定义了以下预处理器:C++ 将PrintContainer预处理器定义转换为C+中的模板+;11,c++,c++11,templates,C++,C++11,Templates,我已经定义了以下预处理器: #define PRINTARRAY(Type, Array, Stream, Separator) \ std::copy(std::begin(Array), std::end(Array), std::ostream_iterator<Type>(Stream, Separator)) #定义PRINTARRAY(类型、数组、流、分隔符)\ std::copy(std::begin(数组)、std::end(数组)、std::ostream_迭代器
#define PRINTARRAY(Type, Array, Stream, Separator) \
std::copy(std::begin(Array), std::end(Array), std::ostream_iterator<Type>(Stream, Separator))
#定义PRINTARRAY(类型、数组、流、分隔符)\
std::copy(std::begin(数组)、std::end(数组)、std::ostream_迭代器(流、分隔符))
我想把它转换成一个模板,这样它就可以自动确定ostream_迭代器的类型,所以我不必传入它
然而,我想知道该怎么做。我的主要问题是:
- 使其适用于所有STL容器
- 将其用于普通阵列(std::begin/end支持哪种?)
有人有什么想法吗?谢谢。您可以执行以下操作:
template <class Con, class Stream>
void print_container(const Con& container, Stream& stream, const typename Stream::char_type* c) {
using value_type = typename std::remove_reference<decltype(*std::begin(container))>::type;
std::copy(std::begin(container), std::end(container), std::ostream_iterator<value_type>(stream, &c);
}
模板
无效打印容器(const Con&container、Stream&Stream、const typename Stream::char\u type*c){
使用value\u type=typename std::remove\u reference::typE
std::copy(std::begin(container)、std::end(container)、std::ostream_迭代器(stream,&c);
}
然后
std::vector<int> v{1,2,3};
print_container(v, std::cerr, " ");
int a [] = {4, 5, 6};
print_container(a, std::cerr, " ");
std::向量v{1,2,3};
打印容器(v,标准::cerr,“”);
int a[]={4,5,6};
打印容器(a,标准::cerr,“”);
印刷品
123456
我可能应该提到,顺便说一句,当你说“所有STL容器”时,这仍然不能适用于所有的STL容器,因为许多STL容器(像所有的地图)实际上迭代了某个东西的
std::pair
s。并且std::pair
没有,你可以执行以下操作:
template <class Con, class Stream>
void print_container(const Con& container, Stream& stream, const typename Stream::char_type* c) {
using value_type = typename std::remove_reference<decltype(*std::begin(container))>::type;
std::copy(std::begin(container), std::end(container), std::ostream_iterator<value_type>(stream, &c);
}
模板
无效打印容器(const Con&container、Stream&Stream、const typename Stream::char\u type*c){
使用value\u type=typename std::remove\u reference::typE
std::copy(std::begin(container)、std::end(container)、std::ostream_迭代器(stream,&c);
}
然后
std::vector<int> v{1,2,3};
print_container(v, std::cerr, " ");
int a [] = {4, 5, 6};
print_container(a, std::cerr, " ");
std::向量v{1,2,3};
打印容器(v,标准::cerr,“”);
int a[]={4,5,6};
打印容器(a,标准::cerr,“”);
印刷品
123456
我可能应该提到,顺便说一句,当你说“所有STL容器”时,这仍然不能适用于所有STL容器,因为许多STL容器(像所有地图一样)实际上迭代某个对象的std::pair
s。而且std::pair
没有通常,STL容器有一个别名value\u type
,它表示容器持有的对象的类型。因此,您可以使用它来获取所包含元素的类型。但对于原始数组,这会失败。在这种情况下,您可以使用de>decltype(*std::begin(c))
来推断类型。通用解决方案是:
template<typename Container>
void PrintArray(std::ostream& Stream, const char* Separator, const Container& c){
std::copy(std::begin(c), std::end(c), std::ostream_iterator<decltype(*std::begin(c))>(Stream, Separator));
}
模板
void打印数组(std::ostream和Stream、常量字符*分隔符、常量容器和c){
std::copy(std::begin(c)、std::end(c)、std::ostream_迭代器(流、分隔符));
}
用法示例:
std::vector<int> v0{1,2 ,3, 5};
PrintArray(std::cout, " ", v0);
std::向量v0{1,2,3,5};
打印阵列(标准::cout,“,v0);
如图所示,STL容器通常有一个别名value\u type
,表示容器所持有的对象的类型。因此,您可以使用它来获取所包含元素的类型。但对于原始数组,这是失败的。在这种情况下,您可以使用decltype(*std::begin(c))
来推断类型。通用解决方案是:
template<typename Container>
void PrintArray(std::ostream& Stream, const char* Separator, const Container& c){
std::copy(std::begin(c), std::end(c), std::ostream_iterator<decltype(*std::begin(c))>(Stream, Separator));
}
模板
void打印数组(std::ostream和Stream、常量字符*分隔符、常量容器和c){
std::copy(std::begin(c)、std::end(c)、std::ostream_迭代器(流、分隔符));
}
用法示例:
std::vector<int> v0{1,2 ,3, 5};
PrintArray(std::cout, " ", v0);
std::向量v0{1,2,3,5};
打印阵列(标准::cout,“,v0);
如图所示,value\u-type
中不需要typename
。char
也不能用作参数标识符。建议使用value\u-type=std::remove\u-reference::type;
哈,是的,非常糟糕的参数名称,谢谢您的更正。@RSahu我也添加了正确的参数。不过当我运行这段代码时,我实际上你可以看到奇怪的输出。很好的解决方案(+1),但我想你可以简化它:如果我没有错,你可以避免使用第三个模板参数(Char
)使用Stream::char\u type
代替。在value\u type
中不需要typename
。而且char
不能用作参数标识符。建议使用value\u type=std::remove\u reference::type;
哈,是的,参数名称很糟糕,谢谢您的更正。@RSahu我也添加了正确的参数。@gh当我运行这段代码时,我实际上看到了奇怪的输出。很好的解决方案(+1),但我想你可以简化它:如果我没有错,你可以避免使用第三个模板参数(Char
),而改用Stream::Char\u type
。@NathanOliver,啊,,,没有看到那部分。Corrected@NathanOliver啊,没有看到那部分。更正