这段代码是用来计数小写字母的,但有个地方不理解
//Literal type that extends string literals:
class conststr
{
const char* p;
std::size_t sz;
public:
template<std::size_t N>
constexpr conststr(const char(&a)[N]) : p(a), sz(N - 1) {}
constexpr char operator[](std::size_t n) const
{
return n < sz ? p[n] : throw std::out_of_range("");
}
constexpr std::size_t size() const { return sz; }
};
constexpr std::size_t countlower(conststr s, std::size_t n = 0,
std::size_t c = 0)
{
return n == s.size() ? c :
s[n] >= 'a' && s[n] <= 'z' ? countlower(s, n + 1, c + 1) :
countlower(s, n + 1, c);
}
// output function that requires a compile-time constant, for testing
template<int n>
struct constN
{
constN() { std::cout << n << '\n'; }
};
int main()
{
std::cout << "the number of lowercase letters in \"Hello, world!\" is ";
constN<countlower("Hello, world!")>(); // implicitly converted to conststr
}
不理解之处:构造的时候 constexpr conststr(const char(&a)[N]),这个 N 是怎么传进来的?
原文在此: https://en.cppreference.com/w/cpp/named_req/LiteralType, 怎么搞这么复杂的 template ,阅读起来有点障碍.
1
nmgwddj 2022-06-23 11:29:46 +08:00
主要是 constexpr 在作怪,参考: https://zh.m.wikipedia.org/zh-hans/Constexpr
|
2
cutepig 2022-06-23 11:45:35 +08:00 via Android
是 template 類型推導出來的。如果用戶輸入數組,那麽就會匹配到這個 ctor ,對應的模板參數會被自動推导出来
|
3
stein42 2022-06-23 11:47:52 +08:00
字符串字面值 "Hello, world!" 的类型为 const char[14],所以推导出 N 为 14 。
|
4
GeruzoniAnsasu 2022-06-23 11:50:38 +08:00
const char(&a)[N] 是一个 有 N 个元素的 char array 的引用
https://stackoverflow.com/questions/13081837/reference-to-an-array-in-c 并且 N 是一个模板参数,因此任意长的 string literal 都能匹配这个模板。N 是模板匹配的结果 |
5
Yienschwen 2022-06-23 12:27:43 +08:00 3
数组长度是数组类型的一部分,不同长度的数组,类型是不同的。所以长度是可以从类型中推断出来的。
顺带提一嘴,数组类型可以隐式转换到指针类型,但两个并不是一个东西。 https://coliru.stacked-crooked.com/a/71dad1817b07736c |
6
realradiolover 2022-06-23 14:50:59 +08:00
字符串常量嘛,编译时可以推导出来
|
7
echoechoin 2022-06-23 15:42:16 +08:00
救命,cpp 太难了
|
8
James369 OP @echoechoin 不会了,其实就是字符数组,我一时也没反应过来。
|