简体   繁体   English

std::array 的维度可以从命令行 arguments 读取吗?

[英]Can the dimension of std::array be read from command line arguments?

I have a C++ code where I decided to use std::array instead of std::vector and I want the size of the array to be read from command line.我有一个 C++ 代码,我决定使用std::array而不是std::vector并且我希望从命令行读取数组的大小。

In practice, this can be summarized with the following snippet在实践中,这可以用下面的片段来总结

#include <iostream>
#include <array>
#include <sstream>

int main(int argc, char* argv[]){

  std::size_t my_size;
  {
    std::istringstream is{argv[1]};
    is >> my_size;
  }
 
  std::cout << my_size<<std::endl;
  std::array<int,my_size> a;
  return 0;
}

The compiler gives the following error, which is due to the fact that my_size must be known at compile time.编译器给出以下错误,这是由于在编译时必须知道my_size

error: the value of 'my_size' is not usable in a constant expression错误:“my_size”的值在常量表达式中不可用
14 | 14 | std::array<int,my_size> a; std::array<int,my_size>一个;

Is there any way to let the size of an std::array to be given from command line?有没有办法让std::array的大小从命令行给出? Or should I definitely use other containers?还是我绝对应该使用其他容器? As dynamic arrays on the heap, or std::vector ?作为堆上的动态 arrays 或std::vector

Types and arrays sizes in particular must be known at compile time, hence the answer is: No.特别是类型和 arrays 大小必须在编译时已知,因此答案是:否。

You can implement some mapping from a runtime value to a compile-time constant.您可以实现一些从运行时值到编译时常量的映射。 Something along the line of沿线的东西

size_t size;
std::cin >> size;
if (size == 10) {
     std::array<int,10> x;
     // use x
} else if (size == 20) [
     std::array<int,20> y;
     // use y
}

However, this is of very limited use, because x and y are of different type.然而,这是非常有限的用途,因为xy是不同的类型。 When the size is only known at runtime it is easier to use a std::vector .当大小仅在运行时已知时,使用std::vector会更容易。

You can convert a relative small size to a constant.您可以将相对较小的尺寸转换为常量。 In C++17 it can be solved this way.在C++17中可以这样解决。

#include <iostream>
#include <array>
#include <sstream>
#include <utility>

constexpr std::size_t MAX_SIZE = 10;

template <class T, class F, T... I>
bool to_const(T value, F&& fn, std::integer_sequence<T, I...>) {
    return (
        (value == I && (fn(std::integral_constant<T, I>{}), true))
        || ... // or continue
    );
}

template <class T, class F>
bool to_const(T value, F&& fn) {
    return value <= MAX_SIZE &&
        to_const(value, fn, std::make_integer_sequence<T, MAX_SIZE + 1>{});
}

int main(int argc, char* argv[]){

  std::size_t my_size;
  {
    std::istringstream is{argv[1]};
    is >> my_size;
  }
 
  std::cout << my_size<<std::endl;

  bool found = to_const(my_size, [](auto N)
  {
      std::array<int, N> a;
  });

  return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM