【问题标题】:How to declare a pointer to pointer to constant in C++?如何在 C++ 中声明一个指向常量的指针?
【发布时间】:2017-05-29 00:51:21
【问题描述】:

我正在尝试编写一个函数来解析命令行参数。这是函数声明:

void parse(int, char const **);

以防万一,我还尝试了(const char)**const char **cchar ** 使用typedef const char cchar。但是,如果我将 char ** 传递给函数,所有这些(正如预期的那样,因为它们应该都是相同的)都会导致错误,如下所示:

void main(int argc, char **argv) {
    parse(argc, argv);

我从 GNU 编译器得到的错误是 error: invalid conversion from 'char**' to 'const char**',而来自 Clang 的错误是 candidate function not viable: no known conversion from 'char **' to 'const char **' for 2nd argument

我已经看到建议的解决方案是声明一个指向 char 的 const 指针 (const char * const *) 的指针,但我不希望任何一个指针都是 const,因为我希望能够修改指针以便可以迭代在使用for(; **argv; ++*argv) 的参数上。如何声明“指向 const char 的非 const 指针的非 const 指针”?

【问题讨论】:

  • C 和 C++ 不一样;你需要选择一种语言。你可以试试char*const*;但是main 想要声明为int main(int argc, char**argv);
  • 在您的情况下,只有数据是 const。指针仍然是可变的。您可以使用parse(argc, const_cast<char const **>(argv)); 将其转换为const
  • “我的印象是所有干净(没有警告)的 C 代码都是有效的 C++ 代码。”——嗯,不。例如,不需要在 C 中强制转换 malloc() 的结果,但这不会在 C++ 中编译。
  • ^ 同样,相同的代码在 C 中可以是正确的,在 C++ 中也可以是正确的,但在每个代码中做不同的事情。 (条件运算符的结合性是我想到的一个例子)

标签: c++ pointers


【解决方案1】:

函数应该声明为:

void parse(int, char const * const *);

在 C++ 中,char ** 可以在所有指针深度处隐式添加const,因此您可以将其称为parse(argc, argv)

在 C 中,const 只能在第一个指针深度添加(这是语言的设计缺陷)。 Here is a dedicated thread。因此,不幸的是,您必须将函数调用为:parse(argc, (char const * const *)argv);

【讨论】:

    【解决方案2】:

    防止修改参数同时允许任何其他const 组合调用函数的最安全签名是这样的:

    parse(int argc, char const* const* argv);
    

    这意味着argv 是一个指针 到一个const 指针 到一个const char

    您可以像这样愉快地迭代参数:

    for(auto arg = argv + 1; *arg; ++arg)
    {
        if(!std::strcmp(*arg, "--help"))
            return print_help();
        else if(!std::strcmp(*arg, "-v") || !std::strcmp(*arg, "--verbose"))
            verbose_flag = true;
        // ... etc...
    }
    

    请注意,不需要接受变量int argc,因为字符数组的数组是空终止的

    所以我通常使用这个:

    struct config
    {
        // program options and switches
    };
    
    config parse_commandline(char const* const* argv);
    

    【讨论】:

    • argv 是否保证为 NULL 终止?我不知道这个事实。在那种情况下,为什么 argc 甚至需要作为参数?
    • @DeadBeetle 是的,这在标准中。
    猜你喜欢
    • 2011-04-01
    • 2012-04-04
    • 2010-09-25
    • 1970-01-01
    • 1970-01-01
    • 2021-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多