2013-07-16 7 views
0

나는 다음과 같은 문제 (아래 코드)를 내놓았다 :자동 템플릿 전문화

template<class T> 
void printname(const T& t){std::cout<<t<<std::endl;} 

template<class T> 
void applyfunc(const T& t, void (*f)(const T&)){(*f)(t);} 
int main(){ 
    const int a=1; 
    applyfunc(a,printname); 
    getchar(); 
    return 0; 
} 

내 문제는 그것이 VC++ 8 (VS2005)로 컴파일합니다이며, GCC, 그 소리 (에 Ubuntu 12.04) vC++ 2008 express로 컴파일하지 못했습니다.

그것은 합법적 인 코드 인 것 같지만 실제로 이유는 없습니다.

누구나 설명해 주시면 감사하겠습니다.

그것이 합법적이라고 가정하면, 비슷한 것이 Functor로 수행 될 수있는 방법이 있습니까?

+1

VS2008 Express에는 어떤 오류가 있습니까? – Praetorian

+0

왜 VS2008이 코드를 거부하는지 또는 다른 사람들이이를 받아들이는지 묻는 중입니까?* 합법적 인 코드 인 것 같지만 실제로 이유를 알지 못합니다. * 또한 비슷한 것이 Functor를 통해 수행 될 수있는 방법이 무엇인지 확실하지 않습니다. * 실제로는 의미합니다. 당신이 해보고 싶은 비슷한 무엇입니까? –

+0

@Praetorian : C2896, C2784 함수 인수 void (*) (const T &)를 함수 인수로 사용할 수 없습니다. – user2588533

답변

2

나는 funcprintname (또는 그 반대)으로 사용한다고 가정합니다.

나는이 코드가 합법적이라고 믿습니다. VS2008 (그리고 VS2010, 현재 VS2012는 유용하지 않습니다)은 컴파일러 버그처럼 보이지 않습니다.

재 : 펑와 비슷한 -이 당신을 위해 그것을 않는 경우 참조 :

#include <iostream> 

struct printname { 
    template<class T> 
    void operator()(const T& t) { std::cout<<t<<std::endl; } 
}; 

template<class T, class F> 
void applyfunc(const T& t, F f) { f(t); } 

int main(){ 
    const int a=1; 
    applyfunc(a, printname()); 
    return 0; 
} 
+0

답해 주셔서 감사합니다. 필자는 펑터 자체가 템플릿 기능을 가졌지 만 멤버 함수가 아닌 경우에만 시도했습니다. 바보 나. – user2588533

0

나는 그것이 대부분의 컴파일러에서 작동 또는 왜 VS2008에 실패 왜 문제가 있는지 여부 등 모르겠습니다. 같은 이름의 다른 오버로드를 참조 할 수 있기 때문에, 기능에

template <typename T> 
void f(T const &) {} 

void g(void (*fn)(std::string const&) {} 

g(f); // compiles 
void (*fn)(double const &) = f; 

포인터는 언어에 조금 특별하다

: 문제는 전자를하는 경우, 우리는이의 단순화 된 버전을 토론 할 수 있습니다. 코드에서 함수의 이름을 사용할 때 컴파일러는 자신이 결정한 오버로드를 결정할 수 없으므로 식의 대상을 사용하여 결정합니다. g(f)의 경우 g 함수는 void (std::string const&) 유형의 함수를 사용하기 때문에 초기화의 경우 f<double> 전문을 해결하는 반면 은 f<std::string>을 의미합니다. 이 언어의 매우 일반적으로 사용되는 기능입니다

참고 : 이름 std::endl 템플릿을 의미

std::cout << std::endl; 

는 :

template <class charT, class traits> 
basic_ostream<charT,traits>& endl(basic_ostream<charT,traits>& os); 

컴파일러는이가 호출되는 것을보고 개체 std::coutbasic_ostream<char,char_traits<char>>이고 operator<<에 대한 호출과 일치하는 유일한 전문화는 다음과 같습니다. charT == chartraits == char_traits<char>을 입력하고 올바른 전문 분야를 선택하십시오.

+0

답해 주셔서 감사합니다. 나는 내 질문을 게시 했으므로 표준을 검사했고 설명 된대로 게시물의 코드가 정확합니다. – user2588533

0

Visual Studio 2010에서 솔루션은 쉽지만 아직 미묘합니다. applyfunc(a,printname<int>); 줄에 printname 뒤에 <int>을 추가하기 만하면됩니다. 컴파일러는 사용할 템플릿 유형을 찾는 데 도움이 필요합니다.

#include <iostream> 

struct printname 
{ 
    template<class T> 
    void operator()(const T& t) 
    { 
     std::cout << t << std::endl; 
    } 
}; 

template<class T, class F> 
void applyfunc(const T& t, F f) 
{ 
    f(t); 
} 

int main() 
{ 
    const int a=1; 
    applyfunc(a, printname<int>);  // Add <int> here 
    return 0; 
}