繁体   English   中英

C ++函数可以返回指向已知长度数组的指针吗?

[英]Can C++ functions return a pointer to an array of known length?

我有一个包含const char s的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_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_; }

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

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

据我string_view 支持constexpr构造函数

但是,这不允许签名const char* c_str() 如果您受此约束,则字符串必须以空值终止,以允许调用者检索长度(通过计数)。

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

#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 ( &)[6] 这个引用非常特殊,因为它只能引用长度为6且与指针不同的char类型的常量数组。 现在可以检索类型信息。
所以std::remove_reference<>::type来拯救,它的type可以指向引用的类型是const char[6]
为了验证这一点,我创建了名为arr const char数组,它是const char[6]而没有指定数组的长度。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM