猿问

为什么模板参数推导在这里不起作用?

为什么模板参数推导在这里不起作用?

我创建了两个简单的函数,它们获取模板参数和一个定义类型的空结构:

//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 valuetemplate <class A>A
temp(typename S<A>::type a1){
    return a1;}//Example 2: get two parameters by reference, perform the sum and return ittemplate <class A, class B>B
temp2(typename S<A>::type a1, B a2)//typename struct S<B>::type a2){
    return a1 + a2;}

参数类型应用于结构S以获得引用。我用一些整数值来调用它们,但是编译器无法推断出参数:

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

错误1错误C2783:“ A temp(S :: type)”:无法推断出“ A”的模板参数

错误2错误C2783:“ B temp2(S :: type,B)”:无法推断出“ A”的模板参数


为什么会这样呢?很难看出模板参数是charint值吗?


www说
浏览 783回答 3
3回答

茅侃侃

就像第一个注释一样,当您提到从属名称时,将使用typename&nbsp;名称。因此,您在这里不需要它。template&nbsp;<class&nbsp;T>struct&nbsp;S{ &nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&&nbsp;type;};关于模板实例化,问题在于typename S<A>::type表征A&nbsp;的非推导上下文。当仅在非推导上下文中使用模板参数时(函数中A的情况),模板参数推导未考虑在内。详细信息在C ++ Standard(2003)的14.8.2.4节中。要使呼叫正常工作,您需要明确指定类型:temp<char>(c);

白衣非少年

它看起来像非推论上下文。根据C ++标准14.8.2.4/4:不可推论的上下文是:使用qualified-id&nbsp;指定的类型的嵌套名称说明符。一种是template-id的类型,其中一个或多个template-arguments是引用template-parameter的表达式。当以包括非推断上下文的方式指定类型名称时,构成该类型名称的所有类型也是非推断的。但是,复合类型可以包括推导类型和非推导类型。[&nbsp;示例:如果将类型指定为A<T>::B<T2>,则T和T2都不能被推导。同样地,如果一个类型被指定为A<I+J>::X<T>,I,J,和T是nondeduced。如果一个类型被指定为void f(typename &nbsp;A<T>::B, &nbsp;A<T>),所述T在A<T>::B是nondeduced但T在A<T>推导。]

江户川乱折腾

推论向前推:template&nbsp;<class&nbsp;T>&nbsp;void&nbsp;f(T);f(2);&nbsp;//&nbsp;can&nbsp;deduce&nbsp;int&nbsp;from&nbsp;T为什么会这样呢?它在向后的方向上不起作用(您的示例):template&nbsp;<class&nbsp;A>&nbsp;void&nbsp;g(typename&nbsp;S<A>::type);很难看出模板参数是char和int值吗?模板推导可以完成一些神奇的(图灵完成)任务,但是我不认为这是其中之一。您可能会使用类似(未经测试)的内容:template&nbsp;<class&nbsp;SA>&nbsp;void&nbsp;h(SA&nbsp;a1){ &nbsp;&nbsp;&nbsp;&nbsp;STATIC_ASSERT(same_type<SA,&nbsp;S<A>::type>::value); &nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;SA::type&nbsp;A; &nbsp;&nbsp;&nbsp;&nbsp;...}使用您喜欢的静态断言库(Boost有两个)。
随时随地看视频慕课网APP
我要回答