查找字符文字的长度(const char *)

Finding the length of a character literals(const char *)

其他的我不清楚,但是直到今天我想知道a的长度 字符文字 ex:"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 的实际推导结果,我使用了 boost 的 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(虽然我可能错了)

Edit : I figured out it is char [21] used pretty_name()

我的问题是,它是如何推导出来的 char [21] 以及为什么它只在我包裹在 struct 而不是自由函数时有效?

Detects the length of the const char* at compile time!! how did it happen?

嗯,事实并非如此。它检测 const char[] 的大小。你可以自己试试:

const char hello[] = "world";
const auto size = sizeof(hello)-1;

其他都是糖。

My question is, how it has got deduced to char [21] [...]?

在 C++ 中,字符串文字的类型是 大小为 X 的连续字符数组,其中 X 被适当地选择。

Why it only works when I wrapped in struct but not in a free function?

这与自由函数与结构无关,而是关于宏参数与函数参数。在 #define BOOST_HANA_STRING(s)return s; returns 中的字符串文字。在 decltype(auto) get(constcharstar ptr)return ptr; returns 中,一个已经腐烂的 const char*

先来看看具体是什么

#define BOOST_HANA_STRING(s)                                                \
    (::boost::hana::string_detail::prepare([]{                              \
        struct tmp {                                                        \
            static constexpr decltype(auto) get() { return s; }             \
        };                                                                  \
        return tmp{};                                                       \
    }()))   

正在做。它本质上做的是创建一个对象,该对象具有 return 字符串文字的功能。如果我们自己制作它可能看起来像

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; }

做同样的事情。我们通过引用获取数组,因为数组的大小是类型的一部分,我们可以推断出它并且 return 它。