【问题标题】:Weird constexpr argument in code代码中奇怪的 constexpr 参数
【发布时间】:2013-06-08 22:34:44
【问题描述】:

我正在尝试理解代码:

#include <iostream>
#include <stdexcept>

// constexpr functions use recursion rather than iteration
constexpr int factorial(int n)
{
    return n <= 1 ? 1 : (n * factorial(n-1));
}

// literal class
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 functions signal errors by throwing exceptions from operator ?:
    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 << "4! = " ;
    constN<factorial(4)> out1; // computed at compile time

    volatile int k = 8; // disallow optimization using volatile
    std::cout << k << "! = " << factorial(k) << '\n'; // computed at run time

    std::cout << "Number of lowercase letters in \"Hello, world!\" is ";
    constN<countlower("Hello, world!")> out2; // implicitly converted to conststr
}

参数是什么

const char(&a)[N]

?我不明白.. 似乎是对数组的引用.. 将它传递给 constexpr 构造函数有什么意义?

【问题讨论】:

  • 是的,它是对固定大小数组的引用。并且因为它的大小是由模板定义的,所以它具有为您可能传递的每个数组大小定义一个 (constexpr) 构造函数的结果(最终结果 sz 设置为您传递的数组的常量大小)。所以这很好,但我不确定constexpr 对于构造函数是否真的有效
  • 好的,一些快速搜索告诉我constexpr 构造函数确实有效。实际上,它们允许在编译时调用构造函数,只留下行为类似于 thing a={0,1,2} 的东西,就像你所期望的那样。

标签: c++ c++11


【解决方案1】:

参数const char(&amp;a)[N]对数组的引用。

它的重点是它允许编译器推断出数组的长度。如果没有引用,const char a[N] 作为参数将等价于const char* a,它不允许推导模板参数N

【讨论】:

  • 这不是唯一的一点。数组是不可变的。普通的char(&amp;a)[N] 不会在这里做。
  • char* a 也不会。但这是一个正交问题,没有迹象表明 David Kermin 对 const 有任何问题。
  • 这不是正交问题。 constexprs 不适用于可变、固定大小的数组。
  • N 的推演与constexpr 的整体是正交的。它在非constexpr 模板上的工作方式完全相同。
【解决方案2】:

这是(连同template&lt;std::size_t N&gt; 部分),一种获取常量字符串大小的方法,因此您可以这样做:

conststr hello("Hello, World!"); 

及以后:

size_t s = hello.size(); 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-24
    • 2014-02-21
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多