Aşağıdaki durumda, bağımlı türler için neden typen kullanmak gerekli değildir?


10

Burada bir tür referansı kaldırma hakkında okuyordum .

Aşağıdaki örneği verir:

#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 ?
}

Özelliklerdeki types std::remove_reference, bağımlı türlerdir.

Olası uygulama

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;};

Ama neden kullanılmıyor typename std::remove_reference</*TYPE*/>::type?

Yanıtlar:


22

Özelliklerdeki types std::remove_reference, bağımlı türlerdir.

Hayır, burada bağımlı isimler değiller . Şablon argümanlar açık şekilde belirtilmemektedir edilmiş int, int&ve int&&. Bu nedenle, türler bu noktada bilinir.

Öte yandan, std::remove_referencebir şablon parametresi ile kullanıyorsanız, ör.

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

ifadenizin artık template parametresine bağlı olduğu için bunun bir tür typenameolduğunu söylemek için kullanmanız gerekir .std::remove_reference<T>::typeT


5

Özetle, typenamederleyicinin

std::remove_reference<int>::type

gerçekten bir tür. Başka bir şablon düşünelim

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

İşte foo::typebir tür. Peki ya birisi,

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

Şimdi typebir tür değil, bir int. Artık şablonun içinde foo kullandığınızda:

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

Derleyicinin foo<T>::typebaşka bir şey değil, gerçekten bir tür olduğundan emin olmalısınız , çünkü sadece derleyiciye bar(ve birincil şablona foo) bakmak bunu bilemez.

Ancak, içinde bir türüyse bağlı değildir, bir şablon parametresi, dolayısıyla derleyici kolayca kontrol edebilirsiniz.mainstd::remove_reference<int>::type


0

Typename anahtar sözcüğü , derleyicinin kaynağı ayrıştırmasına yardımcı olmak için kullanılır. Kimliğin bir değişken adı veya yöntem adı değil, bir tür adı olduğunu gösterir. Ancak, yukarıdaki derleyici gibi durumlarda, kendisini bulabilir, bu nedenle bu anahtar kelime gerekli değildir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.