我有一个包含static constexpr
个数组的const char
的类,我想通过一种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*
一样。
有没有办法做到这一点?
答案 0 :(得分:5)
您是想返回对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_; }
请注意,您不能让函数按值返回原始数组。
答案 1 :(得分:5)
一种现代的选择是返回string_view
,这基本上是指向字符串和长度的指针的组合。这使您的函数的用户可以直接访问长度信息。并且该字符串可以以my_class
的形式以空终止或非空终止的方式存储。
据我所见string_view
supports a constexpr constructor。
但是,这不允许签名const char* c_str()
。如果您受此限制,则该字符串必须以空值结尾,以便调用方可以通过计数来检索长度。
答案 2 :(得分:1)
是的,但是有一种方法需要对代码进行一些小的修改,如下所示,
#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]
。此引用非常特殊,因为它只能引用长度为char
的{{1}}类型的常量数组,并且不同于指针。现在可以检索类型信息。
因此,6
可以挽救了它的std::remove_reference<>::type
可以指向引用所引用的类型,即type
。
为了验证这一点,我创建了名为const char[6]
的{{1}}数组const char
,但未指定数组的长度。