Na podstawie tego, co zostało wyżej omawiając następujące straszny szablon hackery może być wystarczające, aby wyciągnąć to wyłączone. Nie testowałem tego (przepraszam!), Ale jestem prawie pewien, że może to działać lub coś podobnego.
Pierwszym krokiem jest stworzenie klasy szablon, który po prostu trzyma krotka znaków:
template <char... Chars> class CharTuple {};
Teraz zbudujmy adapter, który można przekształcić ciąg C-styl w CharTuple. Aby to zrobić, musimy następujące klasy pomocnika, który jest zasadniczo minusy LISP stylu dla krotek:
template <typename Tuple, char ch> class Cons;
template <char... Chars, char ch> class Cons<CharTuple<Chars... ch>> {
typedef CharTuple<ch, Chars...> type;
}
Niech również zakładać, że mamy 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;
};
Wtedy następujące powinny pozwolić ci przekonwertować ciąg C-styl w krotce:
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;
};
teraz można przekonwertować ciąg C-styl w krotką znaków, można lejek swój ciąg wejściowy za pośrednictwem tego typu odzyskanie krotki . Będziemy musieli zrobić trochę więcej maszyn, aby to zadziałało. Czy TMP nie jest zabawne? :-)
Pierwszym krokiem jest, aby wziąć swój oryginalny kod:
template <char... Chars> class Foo { /* ... */ };
i korzystać z niektórych specjalizacji szablonu, aby przekształcić go
template <typename> class FooImpl;
tempalte <char... Chars> class FooImpl<CharTuple<Chars...>> { /* ... */ };
To kolejna warstwa zadnie; nic więcej.
Wreszcie, powinieneś być w stanie to zrobić:
template <char* str> class Foo {
typedef typename FooImpl<typename StringToChars<str>::type>::type type;
};
Mam nadzieję, że to działa. Jeśli nie, nadal uważam, że warto go publikować, ponieważ jest to prawdopodobnie & epsilon; -zamknij, aby uzyskać prawidłową odpowiedź. :-)
'" abc "' jest zasadniczo takie samo jak ''a', 'b', 'c', '\ 0'', z wyjątkiem wskaźników. –
Kiedyś nie można było utworzyć instancji szablonu w C++ przy użyciu surowego łańcucha C, jeśli szablon został sparametryzowany za pomocą znaku *. Czy naprawili to w C++ 0x? Jeśli tak, myślę, że mam sposób na poprawne wykonanie tego rozszerzenia. – templatetypedef
@Ignacio: Wiem o tym, ale nie możesz napisać '" abc "' dla argumentu "char ..." szablonu. @templatetypedef: Szablon nie jest parametryzowany przez 'char *', jest szablonem variadic nad 'char ...' –