检测c ++数组中的数据类型

时间:2016-11-18 15:18:59

标签: c++ arrays c++11 c++14

这里是打印出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的类型,我想知道实现这一目标的最佳方法是什么。

  1. decltype(*it_b)
  2. decltype(buf[0])
  3. 其他......
  4. 使用这种或那种方法有哪些优缺点?

    这时候假设我们遇到了C风格的数组。

2 个答案:

答案 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>这样的病态容器,其中推断类型可能会导致令人惊讶(和未定义)的行为。