c++ - निम्नलिखित मामले में आश्रित प्रकारों के लिए टाइपनेम का उपयोग करने की आवश्यकता क्यों नहीं है?




c++11 templates (2)

मैं एक प्रकार का संदर्भ हटाने के बारे में पढ़ रहा हूं, here

यह निम्नलिखित उदाहरण देता है:

#include <iostream> // std::cout
#include <type_traits> // std::is_same

template<class T1, class T2>
void print_is_same() {
  std::cout << std::is_same<T1, T2>() << '\n';
}

int main() {
  std::cout << std::boolalpha;

  print_is_same<int, int>();
  print_is_same<int, int &>();
  print_is_same<int, int &&>();

  print_is_same<int, std::remove_reference<int>::type>(); // Why not typename std::remove_reference<int>::type ?
  print_is_same<int, std::remove_reference<int &>::type>();// Why not typename std::remove_reference<int &>::type ?
  print_is_same<int, std::remove_reference<int &&>::type>();// Why not typename std::remove_reference<int &&>::type ?
}

std::remove_reference में type s std::remove_reference गुण निर्भर प्रकार हैं।

संभव कार्यान्वयन

template< class T > struct remove_reference      {typedef T type;};
template< class T > struct remove_reference<T&>  {typedef T type;};
template< class T > struct remove_reference<T&&> {typedef T type;};

लेकिन यह typename std::remove_reference</*TYPE*/>::type उपयोग क्यों नहीं करता है typename std::remove_reference</*TYPE*/>::type ?


std::remove_reference में type s std::remove_reference गुण निर्भर प्रकार हैं।

नहीं, वे यहां आश्रित नाम नहीं हैं। टेम्प्लेट तर्कों को स्पष्ट रूप से int , int& int&& रूप में निर्दिष्ट किया गया है। इसलिए, इस बिंदु पर प्रकार ज्ञात हैं।

दूसरी ओर, यदि आप std::remove_reference उपयोग करते हैं std::remove_reference एक टेम्पलेट पैरामीटर के साथ, उदा

template <typename T>
void foo() {
    print_is_same<int, typename std::remove_reference<T>::type>();
}

फिर आपको यह बताने के लिए typename का उपयोग typename होगा कि std::remove_reference<T>::type एक प्रकार है जैसा कि आपकी अभिव्यक्ति अब टेम्पलेट पैरामीटर T पर निर्भर करती है।


संक्षेप में, संकलक को सुनिश्चित करने के लिए आपको typename आवश्यकता है कि

std::remove_reference<int>::type

वास्तव में एक प्रकार है। कुछ अन्य टेम्पलेट पर विचार करें

template <typename T>
struct foo {
    using type = int;
};

यहाँ foo::type एक प्रकार है। लेकिन क्या होगा अगर कोई लाइन की विशेषज्ञता के साथ आपूर्ति करता है

template <> struct foo<int> {
    int type;
};

अब type एक प्रकार नहीं बल्कि एक int । अब जब आप टेम्पलेट के अंदर फू का उपयोग करते हैं:

template <typanem T> 
struct bar {
    using type = typename foo<T>::type;
};

आपको संकलक को यह सुनिश्चित करना होगा कि foo<T>::type वास्तव में एक प्रकार है, न कि कुछ और, क्योंकि केवल bar (और प्राथमिक टेम्पलेट foo ) को देखकर कंपाइलर को यह पता नहीं चल सकता है।

हालाँकि, आपके main में std::remove_reference<int>::type टेम्पलेट पैरामीटर पर निर्भर नहीं करता है, इसलिए कंपाइलर आसानी से जाँच कर सकता है कि क्या यह एक प्रकार है।







dependent-name