【问题标题】:Can C++ functions return a pointer to an array of known length?C++ 函数可以返回一个指向已知长度数组的指针吗?
【发布时间】:2019-01-21 03:58:27
【问题描述】:

我有一个包含const chars 的static constexpr 数组的类,我想通过c_str() 方法使其可用:

class my_class {
  private:
    static constexpr const char c_str_[6] = {'c', 'h', 'a', 'r', 's', '\0'};
  public:
    static constexpr const char* c_str() {
      return c_str_;
    }
};

这可行,但有一个不幸的效果: 它从类型中删除指向数组的长度:

decltype(my_class::c_str()) // equivalent to const char*

我真正想要的是某种方式来实现这一点:

decltype(my_class::c_str()) // equivalent to const char[6]

我知道无论哪种情况,返回的对象都是一个指针;我只想保留类型中指向数组的长度。有点像decltype("string literal")const char[15],而不是const char*

有没有办法做到这一点?

【问题讨论】:

    标签: c++ c++11 c++14 c++17


    【解决方案1】:

    您的意思是返回对c_str_ 的引用?

    static constexpr decltype(c_str_)& c_str() { return c_str_; }
    

    static constexpr auto& c_str() { return c_str_; }
    

    如果你想要一个指针,只需将& 换成* 并返回&c_str_

    如果要显式引用类型,请使用别名:

    using T = const char[6];
    static constexpr T& c_str() { return c_str_; }
    

    或者如果你真的讨厌自己:

    static constexpr const char (&c_str())[6] { return c_str_; }
    

    请注意,您不能让函数按值返回原始数组。

    【讨论】:

    • 次要注意:这不会像帖子要求的那样使decltype(myclass::c_str())“等同于const char[6]”-它是const char (&)[6],但不可能使用普通数组类型作为返回类型,这对于大多数用途来说已经足够接近了。
    • 太好了,这正是我想要的。我不确定我是如何错过字符串文字是对数组的引用,而不是一直以来的数组。
    • @SumDood 不,字符串文字数组。他们的类型为char const[N]
    • @Barry Actaully,static_assert(std::is_same_v<decltype("test"), const char(&)[5]>); 成功,而 static_assert(std::is_same_v<decltype("test"), const char[5]>); 失败。这似乎表明字符串文字的类型是对 const 字符数组的引用,对吧?
    • @SumDood 编号字符串文字are arrays。只是decltypeadds a reference
    【解决方案2】:

    一个现代的替代方法是返回一个string_view,它基本上是一个指向字符串的指针和长度的组合。这允许您的函数的用户直接访问长度信息。并且该字符串可以以空终止或非空终止的方式存储在my_class

    据我所知string_view supports a constexpr constructor 也是。

    但是这不允许签名const char* c_str()。如果您对此绑定,则字符串必须以 null 结尾,以允许调用者检索长度(通过计数)。

    【讨论】:

    • 我同意 string_view 通常比 raw const char* 更可取,但我主要是从语言的角度来好奇这是否可能。结果是:返回对数组的引用,如接受的答案所示。
    【解决方案3】:

    是的,有一种方法,但需要对您的代码进行一些小修改,如下所示,

    #include <iostream>
    #include <type_traits>
    
    class my_class {
      private:
        static constexpr const char c_str_[6] = {'V', 'a', 'a', 'n', 'i', '\0'};
      public:
        static constexpr auto c_str() ->  const char( &)[6] {
          return c_str_;
        }
    };
    
    int main(int , char *[])
    {
        std::remove_reference< decltype( my_class::c_str())>::type arr = { 'S', 'a', 'a', 'v', 'i', '\0'};
    
        std::cout<< arr<< " is a beautiful name."<< std::endl;
    
        return 0;
    }
    

    输出:Saavi is a beautiful name.

    现在my_class::c_str() 返回引用const char ( &amp;)[6]。这个引用非常特殊,因为它只能引用一个长度为6char 类型的常量数组,并且它与指针不同。现在可以检索类型信息。
    所以std::remove_reference&lt;&gt;::type 来救援,它的type 可以指向引用所指的类型,即const char[6]
    为了验证这一点,我创建了名为arrconst char 数组,即const char[6],但没有指定数组的长度。

    【讨论】:

      猜你喜欢
      • 2011-01-12
      • 1970-01-01
      • 1970-01-01
      • 2021-10-17
      • 1970-01-01
      • 2022-11-21
      • 2010-09-22
      • 2020-04-29
      • 2013-08-24
      相关资源
      最近更新 更多