c++ - 理解具有冲突要求的 const 正确性

标签 c++ arguments constants ros const-cast

错误:Invalid conversion from 'char**' to 'const char**'
类似的问题似乎没有相同的情况(即两个函数在同一结构上具有不同的 const 要求)。如果确实如此,请仅将其标记为重复。

ROS/C++: http://wiki.ros.org/ROS/Tutorials

参数解析器:https://github.com/jamolnng/argparse

我需要通过argv来自 ROS 的函数和来自 argparse 的函数标题。前者取char**后者需要 const *char[] .

代码示例(基本模式仅取自两个库的示例):

int main(int argc, char **argv){
  argparse::ArgumentParser parser("Parser");

  parser.add_argument()
        .names({"-v", "--video"})
        .description("Enable video output for this node.")
        .required(false);
  parser.enable_help();

  //Problem 1: requires argv to be "const *char[]"
  auto err = parser.parse(argc, argv); 
  if (err){ /*error handling*/}

  //Problem 2: requires argv to be non-const
  ros::init(argc, argv, "node_name");

  ...

  return 0;
}

我需要调用这两个函数,但它们都需要相同结构的不同类型。为了清楚起见,函数原型(prototype):
//Declaration 1
Result parse(int argc, const char *argv[]);

//Declaration 2
void ros::init (int & argc,
                char **argv,
                const std::string &name,
                uint32_t options = 0 
                );
  • 有没有办法可以同时调用这两个函数?
  • 为什么这甚至是一个问题?据我了解const在声明 1 中只是一个 promise ,函数 parse()不会修改argv ;为什么这需要变量为const在调用范围内(https://isocpp.org/wiki/faq/const-correctness)。

  • 编辑 - 更多信息:
    凭直觉,我测试了一个最小的工作示例,没有引用 ROS 或 argparsing 库。这是测试代码:
    #include <iostream>
    
    void f(const char **a){
      std::cout << a[1] << std::endl;
    }
    
    int main(int argc, char **argv){
      // Attempt 1
      f(argv); //Causes compilation error.
    
      // Attempt 2
      f(const_cast<const char**>(argv)); //No compilation error and correct functionality
    
      return 0;
    }
    

    我进一步检查了 const_cast导致了我想要的行为(在调用 f() 期间保持不变,仅此而已)。使尝试 2 适应原始问题解决了我的问题,我将在下面添加一个答案。

    我可以接受 const_cast在这里,因为我要提升到 const而不是试图解决不应修改的数据结构。那就是说我不喜欢const_cast而且我不明白为什么在这种情况下似乎有必要。我将保留这个问题,看看是否有人愿意解释这个(回答上面的问题 2),我将发布我的功能解决方案。

    最佳答案

    这是一个实用的解决方案,但我不会接受它作为答案,直到我解释它为什么有效或为什么这似乎是必要的。

    我变了:
    auto err = parser.parse(argc, argv);

    auto err = parser.parse(argc, const_cast<const char**>(argv));
    独立测试(见编辑)表明这产生了我想要的行为,据我所知,在这个特定的上下文中是安全的。我 不要认为这是一个“好”的解决方案。我觉得 const_cast是一种主要的代码气味,但我不知道为什么在这种情况下会很糟糕。

    此解决方案还需要在编译时使用链接标志 -lstdc++fs。

    如果您使用的是 C++17,您也可以尝试 std::as_const() 但我目前仅限于 C++11。

    关于c++ - 理解具有冲突要求的 const 正确性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60952954/

    相关文章:

    c++ - std::cin.fail()问题

    c++ - HRESULT "Class Not Registered"实现简单的 COM 服务器 DLL

    c++ - 不理解通过函数传递的 C++ 参数

    javascript - 使用 javascript 限定符时 safari 和 chrome 之间的不同行为 `const`

    c++ - 适配器模式 : support underlying data that can be const or non-const, 优雅

    c++ - 专门化可变参数模板成员函数

    c++ - 成员函数指针指向另一个对象的方法

    c - 将下一行的参数传递给 C 程序

    javascript - gtag 代码段中的参数变量是什么?

    c# - 未使用的常量是否仍被编译或优化掉?如果没有,如何实现?