2009-08-12 75 views
21

我创建了两个简单的功能,其取得模板参数和一个空的结构限定类型:为什么模板参数演绎在这里不起作用?

//S<T>::type results in T& 
template <class T> 
struct S 
{ 
    typedef typename T& type; 
}; 

//Example 1: get one parameter by reference and return it by value 
template <class A> 
A 
temp(typename S<A>::type a1) 
{ 
    return a1; 
} 

//Example 2: get two parameters by reference, perform the sum and return it 
template <class A, class B> 
B 
temp2(typename S<A>::type a1, B a2)//typename struct S<B>::type a2) 
{ 
    return a1 + a2; 
} 

参数类型被施加到的struct来获取参考。我打电话给他们一些整数值,但编译器无法推断参数:

int main() 
{ 
    char c=6; 
    int d=7; 
    int res = temp(c); 
    int res2 = temp2(d,7); 
} 

错误1个错误C2783:“A 温度(S ::类型)”:无法推断 为模板参数'A'

错误2错误C2783: 'B TEMP2(S ::型,B)':可以为 'A' 不 演绎模板参数


这是怎么发生的?是否很难看到模板参数是charint值?

回答

27

就像第一个音符一样,当您提及从属名称时,使用了typename名称。所以你不需要这里。


template <class T> 
struct S 
{ 
    typedef T& type; 
}; 

关于模板实例,问题是typename S<A>::type表征了A的nondeduced上下文当一个模板参数只用在nondeduced上下文(一个在你的功能的情况下),它没有考虑到考虑模板论证扣除。细节在C++标准的第14.8.2.4节(2003)。

为了使您的工作随叫随到,您需要明确指定类型:


temp<char>(c); 
+2

欢迎来到SO。和+1 :) – 2009-08-12 21:44:17

+0

我编辑了一段时间的报价。你首先,所以+1 :) – 2009-08-12 21:50:15

6

它看起来像nondeduced上下文。根据C++标准14.8.2.4/4:

的nondeduced上下文是:

  • 指使用合格-ID指定的类型的嵌套名称说明符
  • A型是一个模板id在其中一个或多个的模板参数是引用一个模板参数的表达式。

当以包含非衍生上下文的方式指定类型名称时,构成该类型名称的所有类型也都是非派生的。但是,复合类型可以包括推导类型和非推导类型。 [示例:如果类型被指定为A<T>::B<T2>,则两个TT2都是非导出的。同样,如果类型被指定为A<I+J>::X<T>,则不会导致I,JT。如果类型被指定为void f(typename A<T>::B, A<T>),T,A<T>::B未被推出,但推导出T,A<T>。 ]

+0

你可以请用简单的话来解释我这个例子:'使用qualified-id指定的类型的嵌套名称说明符.'我知道嵌套名称说明符是'X ::'和合格的id是以'::'为前缀的,但不能断定或理解整个事物。非常感谢:) – 2012-07-21 17:16:45

+0

它是否像'(**类型**的嵌套名称说明符),它是使用限定的id指定的。 '或'使用限定符**指定的**类型的嵌套名称说明符' – 2012-07-26 17:39:42

4

扣除工作在前进方向:

template <class T> void f(T); 

f(2); // can deduce int from T 

这究竟是为什么?

它不会在向后方向努力(你的例子):

template <class A> void g(typename S<A>::type); 

难道不难看出,模板参数是char和int类型?

模板扣除可以做一些神奇的(图灵完成)的东西,但我不认为这是其中之一。

您可以使用这样的(未经测试):

template <class SA> void h(SA a1) 
{ 
    STATIC_ASSERT(same_type<SA, S<A>::type>::value); 
    typedef typename SA::type A; 

    ... 
} 

使用您喜欢的静态断言库(升压有两个)。

+0

现在也在STL中:http://en.cppreference.com/w/cpp/语言/ static_assert – ibizaman 2013-07-20 12:04:37

相关问题