2017-01-19 5 views
5

나는 책 <을 읽었으며, C++ Templates - Complete Guide>와 학습 된 템플릿 특수화 전문을 제공합니다. (어쩌면 내가이 책의이 부분을 오해)포인터를위한 C++ 템플릿 전문화?

(1) 여기 내 간단한 템플릿입니다 :

$ g++ main.cpp -o main.exe 
main.cpp:10:29: error: non-type partial specialization ‘Function<T*>’ is not allowed 
void Function<T*>(const T* a) 

: g ++ 5.3 컴파일러 보고서 내가 ubuntu16.04 64을 사용

#include <iostream> 

template<typename T> 
void Function(const T& a) 
{ 
    std::cout << "Function<T>: " << a << std::endl; 
} 

template<typename T> 
void Function<T*>(const T* a) 
{ 
    std::cout << "Function<T*>: " << a << std::endl; 
} 

int main(void) 
{ 
    Function(1); 
    Function(1.2); 
    Function("hello"); 
    Function((void*)0x25); 

    return 0; 
} 

, (2) 그러나,이 코드는 정확한 :

#include <iostream> 

template<typename T> 
void Function(const T& a) 
{ 
    std::cout << "Function<T>: " << a << std::endl; 
} 

int main(void) 
{ 
    Function(1); 
    Function(1.2); 
    Function("hello"); 
    Function((void*)0x25); 

    return 0; 
} 

결과를 보여준다

$ g++ main.cpp -o main.exe 
$ ./main.exe 
Function<T>: 1 
Function<T>: 1.2 
Function<T>: hello 
Function<T>: 0x25 

제 질문은 : 포인터 전문화에 대한 책이 잘못 되었습니까? 또는이 책의이 부분의 의미를 잘못 이해하고 있습니까? 또는 다른 것 ?

클래스의 포인터 전문화에 대한 업데이트.

포인터 전문화와

(3) 템플릿 클래스 :

$ g++ main.cpp -o main.exe 
main.cpp: In function ‘int main()’: 
main.cpp:37:27: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] 
    Base<char*> b3("hello"); 
         ^
$ ./main.exe 
12 
2.4 
hello 
0x25 
포인터 전문성이없는

(4) 템플릿 클래스 :

#include <iostream> 

template<typename T> 
struct Base { 
    T member; 

    Base(const T& a) 
     : member(a) 
    { 
    } 

    void hello() 
    { 
     std::cout << member << std::endl; 
    } 
}; 

int main(void) 
{ 
    Base<int> b1(12); 
    Base<double> b2(2.4); 
    Base<char*> b3("hello"); 
    Base<void*> b4((void*)0x25); 

    b1.hello(); 
    b2.hello(); 
    b3.hello(); 
    b4.hello(); 

    return 0; 
} 

#include <iostream> 

template<typename T> 
struct Base { 
    T member; 

    Base(const T& a) 
     : member(a) 
    { 
    } 

    void hello() 
    { 
     std::cout << member << std::endl; 
    } 
}; 

template<typename T> 
struct Base<T*> { 
    T* member; 

    Base(T* a) 
     : member(a) 
    { 
    } 

    void hello() 
    { 
     std::cout << member << std::endl; 
    } 
}; 

int main(void) 
{ 
    Base<int> b1(12); 
    Base<double> b2(2.4); 
    Base<char*> b3("hello"); 
    Base<void*> b4((void*)0x25); 

    b1.hello(); 
    b2.hello(); 
    b3.hello(); 
    b4.hello(); 

    return 0; 
} 

이 코드는 하나의 경고 정확

결과는 같습니다.

$ g++ main.cpp -o main.exe 
main.cpp: In function ‘int main()’: 
main.cpp:39:27: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] 
    Base<char*> b3("hello"); 
         ^
$ ./main.exe 
12 
2.4 
hello 
0x25 

포인터 전문화가 불필요하다는 것을 의미합니까? 아니면 다른 컴파일러에서이 기능이 다르게 동작할까요?

+0

테스트 무엇을 기다리는,

template <typename T, typename std::enable_if_t<!std::is_pointer<T>::value>* = 0> void func(T val) { std::cout << val << std::endl; } template <typename T, typename std::enable_if_t<std::is_pointer<T>::value>* = 0> void func(T val) { func(*val); } 

당신이 간단한 구문을 찾는 경우 : 당신은 이것에 대한 std::enable_if을 사용할 수 있습니까? 그것은 어디에서도 사용되지 않습니까? 동일한 함수가 두 번 선언 된 이유는 무엇입니까? 컴파일러 오류가 무엇입니까? 관련 코드 만 게시하십시오. – stijn

+1

일반적으로 대답은 오류 메시지입니다. 당신이 그것을 보았습니까? – user2079303

+1

clang에 오류가 발생했습니다. '오류 : 함수 템플릿 부분 특수화가 허용되지 않습니다.' GCC는 비슷한 것을보고합니다. 귀하의 질문에 대답해야합니다. – DeiDei

답변

3

오류 메시지는 무엇이 잘못되었는지를 말했다 :

non-type partial specialization ‘Function<T*>’ is not allowed 

당신은 부분적으로 만 유형 (클래스)를 전문으로 할 수 있습니다. 부분적으로 함수를 특수화하려고했습니다. 함수는 유형이 아닙니다. 당신은 그들을 완전히 전문화 할 수 있습니다.

+0

아, 내 실수. – linrongbin

1

두 가지 문제 : 당신은 부분적으로 기능을 전문화 할 수 없습니다

  1. .

  2. (void*)0x25의 동작은 이고 정의되지 않음은입니다. nullptr을 제외하고, 배열의 마지막 요소를 지나서 하나는 스칼라의 주소를 지난 메모리를 제외하고는 소유하지 않은 메모리에 대한 포인터를 설정할 수 없습니다.

+0

(void *) 0x25는 책에서 나온 것이 아니며 제 실수입니다. – linrongbin

4

이미 말씀 드린 것처럼 기능 템플릿의 부분 특수화는 허용되지 않습니다.개념