这里是打印出buf数组的c ++代码,填充0,1,2,...... 254
#include <iterator>
#include <iostream>
#include <numeric>
int main()
{
int buf[255];
auto it_b = std::begin(buf);
auto it_e = std::end(buf);
std::iota(it_b, it_e, 0);
std::copy(it_b, it_e, std::ostream_iterator<decltype(*it_b)>(std::cout, " "));
std::cout << std::endl;
return 0;
}
我试图让它变得通用,因此只有一个地方的类型是明确的int
由于我需要明确声明ostream_iterator
的类型,我想知道实现这一目标的最佳方法是什么。
decltype(*it_b)
decltype(buf[0])
使用这种或那种方法有哪些优缺点?
这时候假设我们遇到了C风格的数组。
答案 0 :(得分:7)
要严格正确,您应该使用std::iterator_traits
:
std::copy(it_b, it_e, std::ostream_iterator<
typename std::iterator_traits<decltype(it_b)>::value_type
>(std::cout, " "));
单独使用decltype(*it_b)
的一个问题是,它会在大多数情况下返回引用,这会混淆您要实例化的外部模板。您也可以手动删除引用:
std::copy(it_b, it_e, std::ostream_iterator<
std::remove_reference_t<decltype(*it_b)>
>(std::cout, " "));
答案 1 :(得分:4)
可能这些都不是你想要的 - 在这两种情况下,你都会以你的类型的左值引用结束,在这种情况下int&
。您可以使用std::decay
来避免它,即
std::copy(it_b, it_e, std::ostream_iterator<std::decay_t<decltype(*it_b)>>(std::cout, " "));
最简单的方法是保持别名类型并使用该别名:
using type = int;
type buf[255];
auto it_b = std::begin(buf);
auto it_e = std::end(buf);
std::iota(it_b, it_e, 0);
std::copy(it_b, it_e, std::ostream_iterator<type>(std::cout, " "));
std::cout << std::endl;
这也适用于像vector<bool>
这样的病态容器,其中推断类型可能会导致令人惊讶(和未定义)的行为。