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

时间:2018-08-01 16:28:48

标签: c++ template-meta-programming boost-hana

我不确定其他人,但是直到今天我想找出一个长度 字符文字,例如:"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中而不起作用时才起作用?

2 个答案:

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

做同样的事情。我们通过引用将数组放入,由于数组的大小是该类型的一部分,我们可以推断出该数组并将其返回。