Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将PrintContainer预处理器定义转换为C+中的模板+;11_C++_C++11_Templates - Fatal编程技术网

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支持哪种?)
我认为关键问题是ostream_迭代器afaik需要包含值的类型,而不是容器的类型


有人有什么想法吗?谢谢。

您可以执行以下操作:

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))>::typ‌​e;
    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::typ‌​E
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))>::typ‌​e;
    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::typ‌​E
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啊,没有看到那部分。更正