简体   繁体   中英

strange typename usage 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)

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM