2016-09-28 6 views
6

मान लीजिए मैं अपने कस्टम स्ट्रिंग वर्ग है:करें स्ट्रिंग टेम्पलेट परोक्ष स्थिरांक चार पारित करके *

class my_string : public std::string 
{ 
    // ... 
} 

और मैं एक टेम्प्लेटेड समारोह जो डिफ़ॉल्ट रूप से my_string के साथ दोनों को स्वीकार करता है बनाना चाहते:

template <typename TString = my_string> 
TString do_something(const TString& input) 
{ 
    // ... 
} 

लेकिन जब मैं से कॉल करने की:

auto result = do_something("abcdef"); 

यह (बेशक)कॉल। कैसे बिना स्पष्ट रूप से (अर्थात do_something("abcdef") लिखते हैं, नहीं do_something<my_string>("abcdef")) प्रकार को निर्दिष्ट do_something<my_string>कॉल करने के लिए यह मजबूर करने के लिए?

+1

नोट: हालांकि केवल एक उदाहरण, std :: स्ट्रिंग से कभी प्राप्त नहीं होता है! –

+6

मैं केवल 'const char []' के लिए एक अधिभार जोड़ूंगा और इसे उस फ़ंक्शन पर अग्रेषित कर दूंगा जिसे आप कॉल करना चाहते हैं। – NathanOliver

+1

लिटल स्ट्रिंग प्रत्यय विकल्प के रूप में मदद कर सकता है: '" abcdef "s' और 'ऑपरेटर'" _my_s' '" abcdef "_my_s' के साथ। – Jarod42

उत्तर

3

"स्ट्रिंग तर्क से निर्माण" के लिए विशेषीकृत करें।

template <typename TString = my_string, 
typename std::enable_if<std::is_base_of<std::string, TString>::value>::type = nullptr> 
TString do_something(const TString& input) 
{ 
    // ... 
} 

template <typename ...Args, 
typename std::enable_if<std::is_constructible<my_string, Args....>::value>::type = nullptr> 
my_string do_something(Args&&... args) 
{ 
    return do_something<my_string>({args}); 
} 
1

क्या आपको वास्तव में फ़ंक्शन टेम्पलेट की आवश्यकता है? सरल कार्य:

my_string do_something(my_string const& input) { ... } 

आपके उपयोग-मामले को हल करता है। आप my_string या स्ट्रिंग शाब्दिक, या यहां तक ​​कि ब्रेस्ड-इनिट-सूची और सबकुछ बस काम कर सकते हैं।


जब से तुम अन्य कारणों के लिए एक टेम्पलेट की जरूरत है, तो आप बस एक अधिभार const char की सरणियों के लिए प्रदान कर सकते हैं:

template <class TString> 
TString do_something(TString const&) { ... } 

template <size_t N> 
my_string do_something(const char (&arr)[N]) { 
    return do_something(my_string{arr, N-1}); 
} 

नोट: वहाँ टेम्पलेट पैरामीटर के लिए एक डिफ़ॉल्ट प्रदान करने के लिए कोई कारण नहीं है TString। उस डिफ़ॉल्ट के अर्थपूर्ण रूप से उपयोग किए जाने का कोई तरीका नहीं है।

+1

यह 'my_string' देता है, जो मैं पुराने कोड में नहीं चाहता जो' std :: string' का उपयोग करता है। – vladon

+0

क्या आप वाकई यहां संदर्भ से सरणी लेना चाहते हैं? मुझे लगता है कि एक 'const char []' पैरामीटर अधिक उपयोगी होगा क्योंकि आप एक सरणी या सूचक पास कर सकते हैं। – NathanOliver

+0

@NathanOliver मैं केवल स्ट्रिंग अक्षर को कैप्चर करना पसंद करूंगा। – Barry

1

पुन

मैं एक टेम्प्लेटेड समारोह जो दोनों my_string साथ डिफ़ॉल्ट रूप से स्वीकार करता है बनाना चाहते

#include <string> 

template< class Type > 
struct Explicit_t_ { using T = Type; }; 

template< class Type > 
using Explicit_ = typename Explicit_t_<Type>::T; 

namespace my { 
    struct String: std::string { using std::string::string; }; 
} // namespace my 

template< class Some_string > 
auto do_something(Explicit_<Some_string> const&) 
    -> Some_string 
{ return "Template func!"; } 

auto do_something(my::String const&) 
    -> my::String 
{ return "my::String!"; } 

#include <iostream> 
using namespace std; 
auto main() 
    -> int 
{ 
    cout << do_something("") << endl;  // Output "my::String!" 
    cout << do_something<std::string>("") << endl; 
} 

आप समारोह टेम्पलेट के लिए बस आगे my::String के लिए अधिभार दे सकते हैं , जब तक आप एक अधिक विशिष्ट या अलग कार्यान्वयन नहीं चाहते हैं।

संबंधित मुद्दे