2012-03-30 3 views
4

을 금지 나는 다음과 같은 한 데모 코드 :자동 형식 유추

In function ‘int main()’:             
11:23: error: call of overloaded ‘func(int)’ is ambiguous 
11:23: note: candidates are: 
2:3: note: T func(const U&) [with int i = 1, T = int, U = int] 
5:3: note: T func(const T&) [with int i = 1, T = int] 

: 그것은 쓸모없는 듯 보이지만 문제를 보여주기 위해 충분합니다, 그래서 내 진짜 코드로 요약 버전입니다

template <int i, typename T, typename U> 
T func(const U &t){return i * t;} 

template <int i, typename T> 
T func(const T &t){return 2 * i * t;} 

int main() 
{ 
     return func<1, int>(1); 
} 

따라서 자동 유형 유추 (템플릿 매개 변수 U의 경우)가 템플릿 함수의 올바른 버전을 선택하는 것에 대한 내 관심사를 방해합니다 (이는 매개 변수가 2 개 뿐인 매개 변수입니다).

기본 템플릿과 특수 템플릿을 사용하려면 두 버전이 필요합니다.

그래서 질문입니다 :이 시점에서 형식을 자동으로 추론하지 않도록 컴파일러에 지시 할 가능성이 있습니까 (예 : 어쨌든 2 개의 매개 변수 만있는 템플릿 사용).

+2

뚜렷한 외에도 의미가 있습니까? (함수 템플리트에 다른 이름을 부여하는 것입니다 - 컴파일러에게 어떤 것을 사용할 지 지시하기 위해 무언가를해야하는 경우 동일한 이름을 갖는 점은 무엇입니까?) – Mat

+0

글쎄 이것은 마지막 선택이 될 것이지만 나는 같은 이름을 공유하는 기능. – Nobody

+0

또한 이름을 변경하여 재 설계를 제안합니다. 나에게 이것은 매우 나쁜 코드 냄새처럼 보인다. 사람들은 이미 오버로드 된 세트의 기능이 사용되는지에 대한 질문에 쉽게 혼란스러워합니다. 이와 같은 것이 존재한다면 그것은 더 어려워지며 나중에 유지 보수가 불가능한 코드로 이어질 수도 있습니다. – LiKao

답변

1

다음과 같은 경우,

template <int i, typename T, typename U> 
T func(const U &t){return i * t;} 

template <int i, typename T> 
T func(const T &t){return 2 * i * t;} 

int main() 
{ 
     return func<1, int>({1}); 
} 

을하지만 귀하의 경우를 func<N>(...)으로 전화를 걸면 두 번째 전화를 걸고 싶은데, func<N, T>(...)으로 전화를 걸면 항상 두 번째 전화를 걸고 싶을뿐입니다. func<N, T, U>(...)에 전화를 걸려면 먼저 U에 대한 매개 변수를 비 감추어 진 컨텍스트로 만들면

template <int i, typename T, typename U> 
T func(typename std::common_type<const U &t>::type t){return i * t;} 

template <int i, typename T> 
T func(const T &t){return 2 * i * t;} 

int main() 
{ 
     return func<1, int>({1}); 
} 
+0

이것이 제가 생각한 것입니다. 내가이 문제를 우회했지만 나는 이것이 문제에 훨씬 더 적합하다고 생각한다. – Nobody

4

당신은 형식 유추를 사용하지 않도록 설정할 수 있지만 오버로드 중 하나 억제하는 SFINAE를 사용할 수 있습니다 기본적으로 추론 유형 U이 유형 T 경우 대체가 실패 할에 대한 템플릿 함수를 만듭니다

template <int N, typename T, typename U> 
typename std::enable_if< !std::is_same<T,U>::value, T >::type 
func(const U & t) { 
    return i*t; 
} 

을, SFINAE는 후보자 집합에서 템플릿을 제거하고 다른 템플릿이 선택됩니다.

C++ 11 지원 컴파일러가없는 경우 enable_ifis_same 템플릿은 간단하게 작성할 수 있습니다. 단지 Google을 사용하거나 댓글을 달아주세요.

당신은 효과적으로 공제를 비활성화합니다 (그러나 int이 경우에 비록 같은 효과가 매개 변수의 목록이 초기화됩니다) 이니셜 라이저 목록, 통과 할 수
+0

이것은 내 문제를 해결할 수 있지만 질문에 대답하지 않습니다. 어쩌면 당신도 이것에 대한 해답을 가지고 있을까요? – Nobody

+1

유형 유추는 언어의 일부이며, 단지 * 비활성화 할 수 없습니다. 위의 경우처럼 일부 경우에는 오버로드를 비활성화하여 일부 상황에서는 고려하지 않을 수 있습니다. –

+0

아마도 나는 다른 표현을 사용해야했습니다. 나는 자동 형 유추를 의미하는 것이 아니라 사실, 템플릿 매개 변수가 자동으로 설정된다는 것을 의미합니다. 그래서 기본적으로 나는 컴파일러에게 알려주는 문법을 요구하고 있었다 :이 매개 변수 시그니처로 템플릿을 가져라! – Nobody