如何在C++中将整个命令行参数集合(char **)作为只读传递?

7
假设我有一个像这样的程序:
#include <iostream>
#include <string>
#include <vector>

// Takes values and outputs a string vector.
std::vector<std::string> foo(const int argc, char* args[]) {
    std::vector<std::string> strings;
    for (int i = 0; i < argc; i++)
        strings.push_back(args[i]);
    return strings;
}

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

    std::vector<std::string> strings = foo(argc, args);

    for (unsigned int i = 0; i < strings.size(); i++)
        std::cout << strings[i] << std::endl;

    return 0;
}

结论是我试图将main()函数的char**参数传递给另一个函数或类。(我知道有更好的方法来实现上述程序,我的问题是关于传递char**参数作为只读的问题)。

问题:

  1. 我发现我不能像第一个参数那样使第二个foo()参数成为const。为什么?char** 不能转换为 const char**吗?
  2. 我想将此参数作为“只读”传递。如果它是字符串,我会通过const引用将其传递,但我不确定如何处理指针?

如果您包含了您尝试过的内容和错误信息,那么问题会更好。 - 463035818_is_not_a_number
1
虽然有点偏题,但如果你想要一个命令行参数的向量,你可以这样创建:std::vector<std::string> args(argv + 1, argv + argc);argv+1是为了跳过程序名称) - Ted Lyngmo
1个回答

9
我发现我不能像第一个foo()参数一样将第二个foo()参数设为const。这是为什么?char**无法转换为const char**?
如果允许这样做,很可能会破坏const正确性。考虑以下情况:
char const *a = "literl";
char *b = nullptr;
char const **c = &b; // This is not allowed in C++. Like your code.
*c = a; // The qualifications match, but now it's b that points at a literal.
*b = 'L'; // Modifying a string literal! Oops!

因此,有很好的理由按原样禁止它。但这并不意味着您完全不能做您想要的事情。只要限制更严格,就可以进行资格转换。总之,这就是要点。
我想将此参数作为“只读”传递。如果它是一个字符串,我会通过const引用传递它,但我不确定如何处理指针?
传递一个指向const char的const指针的指针。最好编写代码来解释:
                                                         // The const here
std::vector<std::string> foo(int const argc, char const* const args[]) {
    std::vector<std::string> strings;
    for (int i = 0; i < argc; i++)
        strings.push_back(args[i]);
    return strings;
}

为什么允许这样做?因为如果我们将它与我之前给出的不好的例子等同起来,c将不再被用于分配给b,因此我们就不会进入错误状态。


@Jaymaican - args 在声明中都不是不可变的。不可变的是它所指向的内容。因此,*argsconst 的。我们无法将无效的内容分配给它。而 **args 则像你想要的那样是 const 的。这样说是否更有意义? - StoryTeller - Unslander Monica
1
@Jaymaican - 指针是一个对象。因此,它可以像任何其他对象一样声明为const :) - StoryTeller - Unslander Monica
1
@Jaymaican - char const* const args[] 正好等于 char const* const *args(我只是不想太大改变你的例子)。现在,从右到左读取。args 是一个指向常量指针的常量指针,限定符应用于左边的东西...除非那里没有任何东西。为了保持一致性,我总是尽可能将其放在右边。 - StoryTeller - Unslander Monica
1
我认为在SO上有关于这个主题的问答,你可以查找以了解更多信息。 - StoryTeller - Unslander Monica
这里是允许转换的标准美学数学定义(某种标准美学)。简单地说(某种标准的简单性):如果您要在例如char ****中添加const,则必须在除最后一个位置外的所有后续位置中也添加constchar ****-> char *const ***-> char *const *const *const * - Arne Vogel
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接