我不确定其他人,但是直到今天我想找出一个长度
字符文字,例如:"somevalue"
我使用strlen()
,现在我正在阅读元编程库Hana,我认为它在C ++社区中是众所周知的,它具有一些处理字符串的代码在编译时,然后是一些代码
#define BOOST_HANA_STRING(s) \
(::boost::hana::string_detail::prepare([]{ \
struct tmp { \
static constexpr decltype(auto) get() { return s; } \
}; \
return tmp{}; \
}()))
基本上它是做什么的
auto temp = BOOST_HANA_STRING("123");
constexpr auto sze = sizeof(temp.get())-1; //mov QWORD PTR [rbp-8], 3
在编译时检测const char *
的长度!它怎么发生的?我以为decltype(auto)
在推导return
语句时有点技巧,所以我写得像
template<typename constcharstar>
decltype(auto) get(constcharstar ptr) { return ptr; }
constexpr auto sze = sizeof(get("123")); //`mov QWORD PTR [rbp-8], 8`(64-bit arch)
我的猜测很糟糕!!因此,为了弄清楚return s
的实际含义,我使用了增强功能的type_index.hpp
auto G = BOOST_HANA_STRING("abcd");
cout<<boost::typeindex::type_id<decltype(G.get())>().raw_name();
Result : which prints `A21_c`
我的直觉是说const char *
被推导为array of 21 char's
(尽管我可能是错的)
编辑:我发现
char [21]
用过pretty_name()
我的问题是,它如何推导到char [21]
上,为什么它仅在包裹在struct
中而不起作用时才起作用?
答案 0 :(得分:2)
在编译时检测
const char*
的长度!怎么发生的?
嗯,事实并非如此。它检测const char[]
的大小。您可以自己尝试:
const char hello[] = "world";
const auto size = sizeof(hello)-1;
还有其他东西就是糖。
我的问题是,它如何推论为
char [21]
[...]?
在C ++中,字符串文字的类型为大小为X的连续字符数组 ,其中适当选择了 X 。
为什么仅当我包裹在struct中而不是自由函数中时才起作用?
这不是关于自由函数还是结构,而是关于宏参数还是函数参数。在#define BOOST_HANA_STRING(s)
中,return s;
返回字符串文字。在decltype(auto) get(constcharstar ptr)
中,return ptr;
返回一个已经衰减的const char*
。
答案 1 :(得分:2)
首先让我们看一看到底是什么
#define BOOST_HANA_STRING(s) \
(::boost::hana::string_detail::prepare([]{ \
struct tmp { \
static constexpr decltype(auto) get() { return s; } \
}; \
return tmp{}; \
}()))
在做。基本要做的是创建一个具有返回字符串文字的功能的对象。如果我们要自己制造,它看起来就像
struct string_size
{
decltype(auto) get() { return "12"; }
};
如果可以的话
std::cout << sizeof(string_size().get());
我们将得到3
。这是因为字符串文字的类型为const char[N]
,而不是const char *
。由于它是一个数组,decltype(auto)
为我们提供了一个引用,sizeof
将显示正确的字符串文字大小。
执行此操作的另一种方法是使用模板功能
template <std::size_t N>
std::size_t size(const char (&arr)[N]) { return N; }
做同样的事情。我们通过引用将数组放入,由于数组的大小是该类型的一部分,我们可以推断出该数组并将其返回。