V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
James369
V2EX  ›  Linux

这个 Cpp 示例代码什么意思,没看懂

  •  
  •   James369 · 6 天前 · 1699 次点击

    这段代码是用来计数小写字母的,但有个地方不理解

    //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 ,阅读起来有点障碍.

    8 条回复    2022-06-23 16:16:20 +08:00
    nmgwddj
        1
    nmgwddj  
       6 天前
    主要是 constexpr 在作怪,参考: https://zh.m.wikipedia.org/zh-hans/Constexpr
    cutepig
        2
    cutepig  
       6 天前 via Android
    是 template 類型推導出來的。如果用戶輸入數組,那麽就會匹配到這個 ctor ,對應的模板參數會被自動推导出来
    stein42
        3
    stein42  
       6 天前
    字符串字面值 "Hello, world!" 的类型为 const char[14],所以推导出 N 为 14 。
    GeruzoniAnsasu
        4
    GeruzoniAnsasu  
       6 天前
    const char(&a)[N] 是一个 有 N 个元素的 char array 的引用
    https://stackoverflow.com/questions/13081837/reference-to-an-array-in-c

    并且 N 是一个模板参数,因此任意长的 string literal 都能匹配这个模板。N 是模板匹配的结果
    Yienschwen
        5
    Yienschwen  
       6 天前   ❤️ 3
    数组长度是数组类型的一部分,不同长度的数组,类型是不同的。所以长度是可以从类型中推断出来的。

    顺带提一嘴,数组类型可以隐式转换到指针类型,但两个并不是一个东西。
    https://coliru.stacked-crooked.com/a/71dad1817b07736c
    realradiolover
        6
    realradiolover  
       6 天前
    字符串常量嘛,编译时可以推导出来
    echoechoin
        7
    echoechoin  
       6 天前
    救命,cpp 太难了
    James369
        8
    James369  
    OP
       6 天前
    @echoechoin 不会了,其实就是字符数组,我一时也没反应过来。
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2055 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 19ms · UTC 00:23 · PVG 08:23 · LAX 17:23 · JFK 20:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.