能够将传递给文字运算符的字符串转换为 MPL 序列将很有用,因为我们将能够根据字符串的内容控制代码生成。以前,我认为这是不可能的,因为 constexpr 函数的参数不被视为函数体内的常量表达式。但是,我想出了在 Clang 3.4.2 和 GCC 4.8.2 下编译的以下解决方法:
#include <cstdint>
#include <iostream>
#include <typeinfo>
struct string
{
const uintmax_t m_str[64];
const size_t m_length;
template <class... Ts>
constexpr string(const Ts... ts) :
m_str{(uintmax_t)ts...}, m_length{sizeof...(Ts)} {}
constexpr size_t size() const { return m_length; }
constexpr size_t length() const { return m_length; }
constexpr uintmax_t operator[](size_t n) const { return m_str[n]; }
};
template <uintmax_t... Ts> struct sequence {};
constexpr auto
operator"" _tag(const char* str, size_t n)
{
return n == 0 ? string{} :
n == 1 ? string{str[0]} :
n == 2 ? string{str[0], str[1]} :
n == 3 ? string{str[0], str[1], str[2]} :
n == 4 ? string{str[0], str[1], str[2], str[3]} :
n == 5 ? string{str[0], str[1], str[2], str[3], str[4]} :
string{str[0], str[1], str[2], str[3], str[4], str[5]};
}
int main()
{
static constexpr auto string = "Hello!"_tag;
using sequence = sequence<string[0], string[1], string[2], string[3], string[4], string[5]>;
std::cout << typeid(sequence{}).name() << std::endl;
}
输出:
sequence<72ul, 101ul, 108ul, 108ul, 111ul, 33ul>
问题
此代码是否调用未定义的行为,还是合法的?