Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

strange typename usage c++11

Tags:

c++

c++11

I have the following code

#include <iostream>
#include <string>
using namespace std;

template<class T> struct Tpl;
template<>        struct Tpl<int>    { void print() { cout << "int"    << endl; } };
template<>        struct Tpl<string> { void print() { cout << "string" << endl; } };

int main() {
  typename Tpl<int>::Tpl{}.print();
  typename Tpl<int>::Tpl<string>{}.print();
  typename Tpl<int>::Tpl<int>{}.print();
  typename Tpl<int>::Tpl::Tpl{}.print();
  typename Tpl<string>::Tpl<int>{}.print();
  typename Tpl<int>::Tpl::Tpl<int>{}.print();
  typename Tpl<string>::Tpl::Tpl<int>::Tpl{}.print();
  typename Tpl<int>::Tpl<string>::Tpl<int>::Tpl<string>::Tpl<int>::Tpl<string>{}.print();
}

that gives the following output

int
string
int
int
int
int
int
string

My question is how typename works in these cases, specially in the last one where you can switch between different template arguments. I would like to know if this behavior is standard or if it's some weirdness on the compiler.

This is the info of the compiler:

> g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.4-2ubuntu1~14.04' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04)
like image 215
Edwin Rodríguez Avatar asked Dec 13 '15 00:12

Edwin Rodríguez


1 Answers

This is because of [temp.local]/1:

Like normal (non-template) classes, class templates have an injected-class-name (Clause 9). The injected-class-name can be used as a template-name or a type-name.

like image 118
Kerrek SB Avatar answered Oct 21 '22 18:10

Kerrek SB