मैंने सही अग्रेषण के बारे में जानने के लिए एक परीक्षण केस स्थापित किया।सी ++ 11: std :: आगे की subtlety: पहचान वास्तव में आवश्यक है?
std::string inner(const std::string& str) {
return "const std::string&";
}
std::string inner(std::string& str) {
return "std::string&";
}
std::string inner(const std::string&& str) {
return "const std::string&&";
}
std::string inner(std::string&& str) {
return "std::string&&";
}
template <typename T> void outer(T&& t) {
std::cout << "t: " << t << std::endl;
std::cout << "perfect forward: " << inner(std::forward<T>(t)) << std::endl;
std::cout << std::endl;
}
void PerfectForwarding()
{
outer("literal");
outer(lvalue);
outer(constlvalue);
outer(rvalue());
outer(constrvalue());
}
std::forward
अपेक्षा के अनुसार काम करता है। दिलचस्प व्यवहार उभर जब मैं पहचान के बिना अपने खुद के आगे समारोह को लागू:
template <typename T> T&& MyForward(T& t)
{
return ((T&&)t);
}
बाहरी में MyForward
साथ std::forward
जगह ठीक उसी परिणाम देता है! व्यवहार सवाल पूछता है कि पहचान का उपयोग क्यों किया जाता है?
संकलक VS2010
अद्यतन 1: प्रकार कटौती को रोकने
AFAIK के संदर्भ में, विशेष प्रकार कटौती नियम केवल टी & & पर सक्रिय है। आगे की परिभाषा पर ध्यान दें, forward(typename identity<T>::type& t)
। तर्क प्रकार में केवल एक & है। असल में, मैंने पहचान का उपयोग करने के लिए माईफोर्ड को बदलने के बाद, (टी & &) कास्टिंग छोड़ दिया, उदाहरण संकलित नहीं होता है। सतह पर, लालू से रावल्यू तक कास्टिंग आगे काम करने लगता है।
अद्यतन 2: जीसीसी 4.5, वही व्यवहार के साथ ideone.com पर परीक्षण किया गया।
"पहचान" से आपका क्या मतलब है? 'Std :: forward' या' remove_reference :: type' के दो ओवरलोड्स? –
kennytm
पहचान पहचान संरचना, आगे की तर्क के प्रकार को संदर्भित करती है: _Ty && आगे (टाइपनाम पहचान <_Ty> :: प्रकार और _Arg) –
यह कुछ पूर्व-मानक हस्ताक्षर होना चाहिए। मानक एक 'T && आगे है (typename remove_reference :: प्रकार और टी)' (और अधिभार लेना '&&')। –
kennytm