注意: constexpr只能用于字面值类型(literal type), string.
用户自定义类型(user-defined),IO库都是不行的.
字面值类型一般是数字,字符,或者双引号内的字符串, 但是我们也可以自己定义字面值类型(literal type).
好吧让我们来看代码吧!
#include <iostream>
constexpr int counter(const int& a, const int& b)noexcept
{
return a + b;
}
class Point{
private:
double x;
double y;
public:
constexpr Point(const double& xVal =0, const double& yVal = 0):x(xVal),y(yVal){}
~Point()=default;
constexpr const double& xValue()const noexcept {return this->x;}
constexpr const double& yValue()const noexcept {return this->y;}
void setX(const double& xVal)noexcept {this->x = xVal;}
void setY(const double& yVal)noexcept {this->y = yVal;}
};
constexpr Point midPoint(const Point& lp, const Point& rp)noexcept
{
return Point(lp.xValue()+2, rp.yValue()+2);
}
int main()
{
std::cout<<counter(1, 2)<<std::endl; //运行时才出来结果.
constexpr int number = counter(2, 3); //编译时期(during compilation),就已经得到了number的结果.
//注意这里的2, 3的效果其实和 consexpr int n3=2; constexpr int n4=3;效果一致的.
constexpr auto n = counter(1, 2); //也是编译时期获得结果.
int n2 = counter(1, 3); //运行(run-time)时才得到n2的结果.
std::cout<<number<<std::endl;
constexpr Point p1(9.4, 8.3);
constexpr Point p2(5.5, 6.6);
Point p3 = midPoint(p1, p2); //运行时才得出p3。
constexpr Point p4 = midPoint(p1, p2); //编译器就得到了p4.
constexpr Point p5 = midPoint(Point(1, 2), Point(3, 4)); //编译时期得到p5.
return 0;
}
再来看一个Demo我们如何自定义(literal type):
#include <iostream>
#include <stdexcept>
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
}