Исходя из того, что я обсуждал выше, следующий ужасный взлом шаблонов может быть достаточным, чтобы осуществить это. Я не проверял это (извините!), Но я уверен, что это или что-то похожее может сработать.
Первым шагом является создание шаблонного класса, который просто содержит кортеж из символов:
template <char... Chars> class CharTuple {};
Теперь давайте создадим адаптер, который может преобразовывать строку в стиле C в CharTuple. Чтобы сделать это, нам понадобится следующий вспомогательный класс, который по сути является консулом в стиле LISP для кортежей:
template <typename Tuple, char ch> class Cons;
template <char... Chars, char ch> class Cons<CharTuple<Chars... ch>> {
typedef CharTuple<ch, Chars...> type;
}
Давайте также предположим, что у нас есть выражение meta-if:
template <bool Condition, typename TrueType, typename FalseType> class If {
typedef typename TrueType::type type;
};
template <typename TrueType, typename FalseType> class If<False> {
typedef typename FalseType::type type;
};
Тогда следующее должно позволить вам преобразовать строку в стиле C в кортеж:
template <typename T> class Identity {
typedef T type;
};
template <char* str> class StringToChars {
typedef typename If<*str == '\0', Identity<CharTuple<>>,
Cons<*str, typename StringToChars<str + 1>::type>>::type type;
};
Теперь, когда вы можете преобразовать строку в стиле C в кортеж символов, вы можете направить вашу входную строку через этот тип, чтобы восстановить кортеж. Нам нужно сделать немного больше машин, чтобы все заработало. Разве TMP не весело? : -)
Первый шаг - взять ваш оригинальный код:
template <char... Chars> class Foo { /* ... */ };
и использовать некоторую специализацию шаблона, чтобы преобразовать его в
template <typename> class FooImpl;
tempalte <char... Chars> class FooImpl<CharTuple<Chars...>> { /* ... */ };
Это просто еще один слой косвенности; больше ничего.
Наконец, вы должны быть в состоянии сделать это:
template <char* str> class Foo {
typedef typename FooImpl<typename StringToChars<str>::type>::type type;
};
Я действительно надеюсь, что это работает. Если это не так, я все еще думаю, что это стоит опубликовать, потому что это, вероятно, & epsilon; : -)