使用完全支持的 C++11 编译器,constexpr
我们可以使用constexpr
使用函数的构造constexpr
函数,该函数编译为非常量表达式主体,以防不满足尾随零字符前提条件,导致编译失败并出现错误。以下代码扩展了 UncleBens 的代码,灵感来自Andrzej 的 C++ 博客中的一篇文章:
#include <cstdlib>
class Literal
{
public:
template <std::size_t N> constexpr
Literal(const char (&str)[N])
: mStr(str),
mLength(checkForTrailingZeroAndGetLength(str[N - 1], N))
{
}
template <std::size_t N> Literal(char (&str)[N]) = delete;
private:
const char* mStr;
std::size_t mLength;
struct Not_a_CString_Exception{};
constexpr static
std::size_t checkForTrailingZeroAndGetLength(char ch, std::size_t sz)
{
return (ch) ? throw Not_a_CString_Exception() : (sz - 1);
}
};
constexpr char broke[] = { 'a', 'b', 'c' };
//constexpr Literal lit = (broke); // causes compile time error
constexpr Literal bla = "bla"; // constructed at compile time
我用 gcc 4.8.2 测试了这段代码。使用 MS Visual C++ 2013 CTP 编译失败,因为它仍然不完全支持constexpr
(constexpr
成员函数仍然不支持)。
也许我应该提到,我的第一个(也是首选)方法是简单地插入
static_assert(str[N - 1] == '\0', "Not a C string.")
在构造函数体内。它因编译错误而失败,似乎constexpr
构造函数必须有一个空的主体。我不知道,这是否是 C++11 的限制以及未来的标准是否会放宽。