ऐसा लगता है कि आप क्या चाहते हैं Boost। MPL का boost::mpl::string
। का उपयोग करके संकलन समय पर mpl::string
को एक अभिन्न प्रकार में कनवर्ट करने के लिए मेटाफंक्शन लिखना अधिक कम या कम होगा (या स्ट्रिंग शब्दशः मान्य अभिन्न मान का प्रतिनिधित्व नहीं करता है तो संकलित करने में विफल)।
संपादित करें:
मैं पूरी तरह सुनिश्चित करें कि आप जो खोज रहे हैं, तो यहाँ नहीं हूँ प्रभावी रूप से दो अलग व्याख्या के आधार पर जवाब है:
यदि क्या आप 'की तलाश है संकलन-समय स्ट्रिंग-टू-इंटीग्रल-वैल्यू रूपांतरण (उदाहरण के लिए "425897"
को अभिन्न स्थिरके रूप में पहचाना जा सकता है संकलन समय पर), फिर एक Boost.MPL के रूप में मैं सुझाव का उपयोग कर सकते हैं:
#include <cstddef>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_signed.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/char.hpp>
#include <boost/mpl/contains.hpp>
#include <boost/mpl/end.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/find_if.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/integral_c.hpp>
#include <boost/mpl/minus.hpp>
#include <boost/mpl/negate.hpp>
#include <boost/mpl/next.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/pair.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/reverse_fold.hpp>
#include <boost/mpl/size_t.hpp>
#include <boost/mpl/string.hpp>
#include <boost/mpl/times.hpp>
#include <boost/mpl/vector.hpp>
namespace details
{
namespace mpl = boost::mpl;
typedef mpl::vector10<
mpl::char_<'0'>, mpl::char_<'1'>, mpl::char_<'2'>, mpl::char_<'3'>,
mpl::char_<'4'>, mpl::char_<'5'>, mpl::char_<'6'>, mpl::char_<'7'>,
mpl::char_<'8'>, mpl::char_<'9'>
> valid_chars_t;
template<typename IntegralT, typename PowerT>
struct power_of_10;
template<typename IntegralT, std::size_t Power>
struct power_of_10<IntegralT, mpl::size_t<Power> > : mpl::times<
power_of_10<IntegralT, mpl::size_t<Power - 1u> >,
mpl::integral_c<IntegralT, 10>
> { };
template<typename IntegralT>
struct power_of_10<IntegralT, mpl::size_t<1u> >
: mpl::integral_c<IntegralT, 10>
{ };
template<typename IntegralT>
struct power_of_10<IntegralT, mpl::size_t<0u> >
: mpl::integral_c<IntegralT, 1>
{ };
template<typename IntegralT, typename StringT>
struct is_negative : mpl::and_<
boost::is_signed<IntegralT>,
boost::is_same<
typename mpl::front<StringT>::type,
mpl::char_<'-'>
>
> { };
template<typename IntegralT, typename StringT>
struct extract_actual_string : mpl::eval_if<
is_negative<IntegralT, StringT>,
mpl::pop_front<StringT>,
mpl::identity<StringT>
> { };
template<typename ExtractedStringT>
struct check_valid_characters : boost::is_same<
typename mpl::find_if<
ExtractedStringT,
mpl::not_<mpl::contains<valid_chars_t, mpl::_> >
>::type,
typename mpl::end<ExtractedStringT>::type
> { };
template<typename ExtractedStringT>
struct pair_digit_with_power : mpl::first<
typename mpl::reverse_fold<
ExtractedStringT,
mpl::pair<mpl::vector0<>, mpl::size_t<0> >,
mpl::pair<
mpl::push_back<
mpl::first<mpl::_1>,
mpl::pair<mpl::_2, mpl::second<mpl::_1> >
>,
mpl::next<mpl::second<mpl::_1> >
>
>::type
> { };
template<typename IntegralT, typename ExtractedStringT>
struct accumulate_digits : mpl::fold<
typename pair_digit_with_power<ExtractedStringT>::type,
mpl::integral_c<IntegralT, 0>,
mpl::plus<
mpl::_1,
mpl::times<
mpl::minus<mpl::first<mpl::_2>, mpl::char_<'0'> >,
power_of_10<IntegralT, mpl::second<mpl::_2> >
>
>
> { };
template<typename IntegralT, typename StringT>
class string_to_integral_impl
{
BOOST_MPL_ASSERT((boost::is_integral<IntegralT>));
typedef typename extract_actual_string<
IntegralT,
StringT
>::type ExtractedStringT;
BOOST_MPL_ASSERT((check_valid_characters<ExtractedStringT>));
typedef typename accumulate_digits<
IntegralT,
ExtractedStringT
>::type ValueT;
public:
typedef typename mpl::eval_if<
is_negative<IntegralT, StringT>,
mpl::negate<ValueT>,
mpl::identity<ValueT>
>::type type;
};
}
template<typename IntegralT, typename StringT>
struct string_to_integral2
: details::string_to_integral_impl<IntegralT, StringT>::type
{ };
template<typename IntegralT, int C0, int C1 = 0, int C2 = 0,
int C3 = 0, int C4 = 0, int C5 = 0, int C6 = 0, int C7 = 0>
struct string_to_integral : string_to_integral2<
IntegralT,
boost::mpl::string<C0, C1, C2, C3, C4, C5, C6, C7>
> { };
प्रयोग दिखाई देगा:
type search(int tag) { /*impl... */ }
void foo()
{
type value = search(string_to_integral<int, '4258','97'>::value);
}
// OR, if you still want to maintain the separation
// between `search` and `internal_search`
type internal_search(int tag) { /*impl... */ }
template<typename TagStringT>
type search()
{
return internal_search(string_to_integral2<int, TagStringT>::value);
}
void foo()
{
typedef boost::mpl::string<'4258','97'> tag_t;
type value = search<tag_t>();
}
ऋणात्मक संख्याओं के लिए समर्थन कार्यान्वित किया जाता है, अतिप्रवाह का पता लगाने के लिए समर्थन नहीं है (लेकिन आपका कंपाइलर शायद एक चेतावनी देगा)।
यदि क्या आप देख रहे हैं संकलन समय स्ट्रिंग-से-अभिन्न-मूल्य मानचित्रण (जैसे इतना "SomeTag"
अभिन्न निरंतर 425897
संकलन समय पर के रूप में पहचाना जा सकता है), तो है Boost.MPL अभी भी समस्या का हल है, लेकिन सभी स्ट्रिंग-से-अभिन्न-मूल्य मैपिंग संकलन समय पर जाना जाता है और केन्द्र में पंजीकृत होना जरूरी है:
0:
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/integral_c.hpp>
#include <boost/mpl/map.hpp>
#include <boost/mpl/pair.hpp>
#include <boost/mpl/string.hpp>
#include <boost/mpl/void.hpp>
namespace details
{
namespace mpl = boost::mpl;
typedef mpl::map<
mpl::pair<
mpl::string<'Some','Tag'>,
mpl::integral_c<int, 425897>
>,
mpl::pair<
mpl::string<'Some','Othe','rTag'>,
mpl::integral_c<int, -87>
>,
mpl::pair<
mpl::string<'AnUn','sign','edTa','g'>,
mpl::integral_c<unsigned, 7u>
>
> mappings_t;
template<typename StringT>
struct map_string_impl
{
typedef typename mpl::at<
mappings_t,
StringT
>::type type;
BOOST_MPL_ASSERT_NOT((boost::is_same<type, mpl::void_>));
};
}
template<typename StringT>
struct map_string2 : details::map_string_impl<StringT>::type { };
template<int C0, int C1 = 0, int C2 = 0, int C3 = 0,
int C4 = 0, int C5 = 0, int C6 = 0, int C7 = 0>
struct map_string : map_string2<
boost::mpl::string<C0, C1, C2, C3, C4, C5, C6, C7>
> { };
प्रयोग कैसा लगेगा
type search(int tag) { /*impl... */ }
void foo()
{
type value = search(map_string<'Some','Tag'>::value);
}
// OR, if you still want to maintain the separation
// between `search` and `internal_search`
type internal_search(int tag) { /*impl... */ }
template<typename TagStringT>
type search()
{
return internal_search(map_string2<TagStringT>::value);
}
void foo()
{
typedef boost::mpl::string<'Some','Tag'> tag_t;
type value = search<tag_t>();
}
mappings_t
क्या मैप किया अभिन्न मान सभी एक ही अंतर्निहित प्रकार का होना नहीं की जरूरत के रूप में प्रदर्शित अपने स्ट्रिंग-से-अभिन्न-मूल्य मैपिंग बनाए रखने के लिए संपादित करने के लिए, और, की जरूरत है।
या तो मामले में, क्योंकि मानचित्रण संकलन समय पर किया जाता है, search
/internal_search
(एक int
लेने वास्तविक कार्यान्वयन के साथ एक) टेम्पलेट पैरामीटर के रूप में के बजाय एक के रूप में अभिन्न मूल्य लेने के लिए किया जा सकता है ऐसा करने पर फ़ंक्शन पैरामीटर इसके कार्यान्वयन के लिए समझ में आता है।
उम्मीद है कि यह आपके प्रश्नों का उत्तर देगा।
एक विकल्प के रूप में, हो सकता है 'toNumber' सभी टैग का एक नक्शा रख सकता है कि उसने देखा है, और उनके संख्यात्मक मूल्य, ताकि आपको प्रति टैग एक बार रूपांतरण लागत का भुगतान करना पड़े? यह संकलन समय पर मूल्यांकन करने के लिए टेम्पलेट भाषा का उपयोग करने के रूप में उतना कुशल नहीं है, लेकिन मैं शर्त लगाता हूं कि कोड इस तरह से बहुत अधिक पठनीय और रखरखाव योग्य होगा। – aroth
टीटीबीओएमके आप संकलन समय पर तारों पर फिर से नहीं जा सकते हैं। – sbi
@aroth मुझे लगता है कि toNumber फ़ंक्शन खोज से तेज़ है, भले ही मैं लॉग 2 खोज का उपयोग करूं। – Felics