2015-12-13 22 views
8

Tôi có đoạn code saulạ sử dụng typename C++ 11

#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(); 
} 

cung cấp cho đầu ra sau đây

int 
string 
int 
int 
int 
int 
int 
string 

Câu hỏi của tôi là như thế nào typename công trình trong những trường hợp này, đặc biệt trong cuối cùng một nơi bạn có thể chuyển đổi giữa các đối số mẫu khác nhau. Tôi muốn biết nếu hành vi này là tiêu chuẩn hoặc nếu đó là một số weirdness trên trình biên dịch.

Đây là thông tin của trình biên dịch:

> 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) 

Trả lời

9

Đây là vì [temp.local]/1:

Giống như (không mẫu) các lớp học bình thường, lớp mẫu có một tên lớp được tiêm (Điều 9). Tên lớp được tiêm có thể được sử dụng làm tên mẫu hoặc loại tên.

+1

Wow, Rất thú vị! Vì vậy, nó giống như mọi class giống như 'class SomeName {using SomeName = SomeName; }; '? –

+2

Loại. Xem http://stackoverflow.com/questions/25549652/c-why-is-there-injected-class-name –

+0

@ melak47: Tôi không chắc chắn liệu có phải 'typename' là bắt buộc hay không. Tôi chỉ cố gắng giải thích tại sao tên này có thể được sử dụng làm tên tập tin và tên mẫu ... –

Các vấn đề liên quan