के लिए पॉलिमॉर्फिक सेटटर मैं टेम्पलेट प्रकारों के साथ boost :: संस्करण का उपयोग करने की कोशिश कर रहा हूं। उदाहरण के लिए, मेरे पास एक टेम्पलेट प्रकार Tag<T>
है और boost :: संस्करण AnyTag में Tag<double>
, Tag<int>
और Tag<std::string>
जैसे प्रकार शामिल हैं। प्रत्येक Tag<T>
प्रकार टी के सदस्यों अब है, मैं एक कंटेनर में उन वेरिएंट डाल करने के लिए और केवल रनटाइम के दौरान मान निर्दिष्ट जैसे चाहते हैं,Boost :: variant
for(AnyTag & tag: AllTags) {
setValue(tag, getValueFromXml());
}
समारोह setValue(AnyTag &tag, T &val)
में AnyTag टैग के क्रम प्रकार का उपयोग करना चाहिए सही मूल्य के साथ टैग सही ढंग से असाइन करने के लिए आदेश। समस्या को हल करने का मेरा प्रयास नीचे पाया जा सकता है और यह किसी अन्य संस्करण का उपयोग करता है जिसमें केवल संभावित टी प्रकार शामिल होते हैं जिनका उपयोग AnyTag (TagValueType) में किया जा सकता है।
template<typename T, typename = void>
class Tag {};
template <typename T>
class Tag<T, EnableIf<std::is_arithmetic<T>>> {
public:
T value = 0;
std::string address = "";
T maxValue = std::numeric_limits<T>::max();
typedef T value_type;
};
template <typename T>
class Tag<T, DisableIf<std::is_arithmetic<T>>> {
public:
T value;
std::string address = "";
typedef T value_type;
};
typedef boost::variant<Tag<std::string>,
Tag<double>,
Tag<int>,
> AnyTag;
typedef boost::variant<std::string, double, int> TagValueType;
class tag_set_value_visitor: public boost::static_visitor<void>
{
const TagValueType & value;
public:
tag_set_value_visitor(const TagValueType & val): value(val){}
template <typename T>
void operator()(T & tag) const
{
tag.value = boost::get<typename T::value_type>(value);
}
};
inline void setValue(AnyTag & tag, const TagValueType & val) {
assert(tag.which() == val.which());
boost::apply_visitor(tag_set_value_visitor(val), tag);
}
दुर्भाग्य से, यह तरीका नहीं है मैं क्योंकि संकलन के दौरान उदाहरण के लिए क्या चाहते हैं वहाँ समस्या नहीं है अगर मैं निम्न कार्य करें:
AnyTag a = Tag<int>();
setValue(a, double(1.3));
लेकिन रनटाइम के दौरान, बढ़ावा पुस्तकालय प्रकार मेल नहीं खाता का पता लगाता है और कार्यक्रम दुर्घटनाग्रस्त हो जाता है।
तो, मेरा समाधान एक प्रकार का मिरर है जो सिर्फ समस्या को स्थगित करता है।
मैं जो सेट करना चाहता हूं वह एक सेटव्यू (AnyTag & टैग, टी & वैल) है जहां टी AnyTag का रनटाइम प्रकार है।
मुझे लगता है कि संस्करण का विज़िटर ऐसा करने का प्रयास करता है, लेकिन इस मामले में एक समस्या है क्योंकि जब हम विज़िटर का निर्माण करते हैं तो हमें उस प्रकार को जानना चाहिए जिसे हम उपयोग करने जा रहे हैं।
इस समस्या के बारे में कोई विचार या कोई विचार?
पीएस .: लंबी पोस्ट के लिए खेद है लेकिन मुझे कम शब्दों के साथ मेरी विचार प्रक्रिया को समझाने का कोई तरीका नहीं मिला।
'सेटवैल्यू (ए, डबल (1.3))' में, आप संकलक को समस्या का पता लगाने की अपेक्षा कैसे करते हैं जब समस्या _run-time_ प्रकार 'a' है? – Nemo
नीमो, मैं नहीं करता। मैंने कहीं लिखा है कि मैं जो कर रहा हूं वह सिर्फ समस्या को स्थगित कर रहा है।क्या मैं करना चाहते हैं ("आराम" वाक्य रचना में) है: उत्पन्न setValue (AnyTag :: टैग 1) संकलक और, पूर्णांक और वैल) setValue (AnyTag :: टैग और, डबल और वैल) 2) और उसके बाद रनटाइम के दौरान polymorphically Anytag के रन-टाइम प्रकार के आधार पर सही सेटवैल्यू (...) का चयन करें। –
CuriousNik
मैं समझता हूं कि प्रेषण सी ++ में इस तरह से नहीं हो सकता है, इसलिए मैं सोच रहा था कि शायद कोई चाल (विज़िटर पैटर्न के साथ) जानता है जो इस समस्या को हल कर सकता है। – CuriousNik