【问题标题】:Passing a char pointer to a function accepting a reference to a char array将 char 指针传递给接受对 char 数组的引用的函数
【发布时间】:2019-03-04 17:57:44
【问题描述】:

我正在尝试调用此方法

#define SIZE 16
void DoSomething(char(&value)[SIZE])
{
}

从这个方法:

void BeforeDoingSomething(char* value, int len)
{
    if (len == SIZE)
    {
        DoSomething(value);
    }
}

尝试这样做会给我这个错误:

“char (&)[16]”类型的引用(非 const 限定)不能用“char *”类型的值初始化

关于如何让编译器接受在函数BeforeDoingSomething 中传递的value 的任何提示?

【问题讨论】:

  • 您如何确定value 指向char[SIZE] 的开头?你也许可以reinterpret_cast,但我不确定。无论如何我都不推荐。
  • 我发现了一个相关的问题here。虽然严格来说它可能会解决您的问题,但这感觉就像一个尴尬的情况。我会鼓励你考虑稍微重新设计。为什么DoSomething 总是需要一个长度为SIZE 的数组?为什么BeforeDoingSomething 不能总是使用长度为SIZE 的数组而不是指针和长度?
  • 这种尴尬情况的原因是因为这是在 DLL 中发生的。编写DoSomething 的开发人员就是这样写的,当调用我的DLL 时,它的形式是BeforeDoingSomething 内部的形式。当涉及到调用 DLL 的人(调用者不会是 C++)时,我什至不知道如何执行char(&value)[SIZE] 之类的东西

标签: c++


【解决方案1】:

正如错误所解释的,您不能使用指针初始化对数组的引用。

当且仅当您可以证明 value 确实指向适当类型的数组(的第一个元素),那么您可以做的是显式地重新解释指针,并将其间接引用:

DoSomething(*std::launder(reinterpret_cast<char(*)[SIZE]>(value)));

【讨论】:

  • std::launder 在这里是因为严格的别名规则吗?
  • @Quimby 完全正确。
  • 我认为这里的洗钱是强制性的,在char数组的情况下也是如此。
  • @user2079303 谢谢。
  • @Quimby:不。它与严格的别名规则无关。它可以获取一个实际指向 char 数组的指针(因为 reinterpret_cast 不会为您这样做,因为指针不可相互转换)。
【解决方案2】:

你可以这样做,但前提是value指向的地址有char[16]

DoSomething(*std::launder(reinterpret_cast<char (*)[16]>(value)));

与第一个例子here的情况相同。

【讨论】:

    【解决方案3】:

    @user2079303 建议的 std::launder 的使用是一个不错的选择,如果您确定该值确实指向他们答案中提到的正确大小的数组。

    另一种方法:由于在这种情况下SIZE 相当小,因此创建value 的临时副本并将其传递给DoSomething() 可能更安全/更简单。但这一切都取决于DoSomething() 实际在做什么(例如,它是否修改了传递给它的数组)。例如:

    #include <iostream>
    #include <vector>
    #include <string>
    
    constexpr int SIZE = 16 ;
    
    void DoSomething(char (&value)[SIZE])
    {
        std::cout << "Do it!" << std::endl ;
    }
    
    void BeforeDoingSomething(char* value, int len)
    {
        if (len == SIZE)
        {
            char tmp_array[SIZE] ;
            std::copy(value, value + len, tmp_array) ;
            DoSomething(tmp_array);
        } else {
            std::cout << "Length: " << len << std::endl ;   
        }
    }
    
    int main()
    {
        std::string foo (SIZE, '-') ;
        BeforeDoingSomething(foo.data(), foo.size()) ;
    
        std::vector<char> bar (SIZE) ;
        BeforeDoingSomething(bar.data(), bar.size()) ;
    
        std::string qux ;
        BeforeDoingSomething(qux.data(), qux.size()) ;
    
        return 0 ;   
    }
    

    在线试用here

    【讨论】:

      猜你喜欢
      • 2016-03-27
      • 1970-01-01
      • 1970-01-01
      • 2021-09-07
      • 1970-01-01
      • 2012-07-28
      • 1970-01-01
      • 2021-12-02
      相关资源
      最近更新 更多