完全にサポートされているC++11コンパイラでは、関数を使用してコンストラクタを使用constexpr
できます。このコンストラクタは、末尾のゼロ文字の前提条件が満たされない場合に非定数式の本体にコンパイルされ、コンパイルがエラーで失敗します。次のコードは、UncleBensのコードを拡張したもので、AndrzejのC++ブログの記事に触発されています。constexpr
constexpr
#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
このコードをgcc4.8.2でテストしました。MS Visual C ++ 2013 CTPを使用したコンパイルは、まだ完全にはサポートされていないため失敗しましたconstexpr
(constexpr
メンバー関数はまだサポートされていません)。
おそらく私が言及する必要があるのは、私の最初の(そして好ましい)アプローチは単に挿入することでした
static_assert(str[N - 1] == '\0', "Not a C string.")
コンストラクター本体で。コンパイルエラーで失敗し、constexpr
コンストラクターは空の本体を持っている必要があるようです。これがC++11の制限であるかどうか、また将来の標準によって緩和される可能性があるかどうかはわかりません。