2017-10-04 55 views
2

可有人请帮助我理解为什么下面的代码不会编译:没有投投虽然操作定义

template< typename T > 
class A 
{}; 

template< typename U > 
class wrapper 
{ 
    public: 
    // cast operator 
    operator wrapper< A<void> >() 
    { 
     return wrapper< A<void> >{}; 
    } 

}; 

template< typename T > 
void foo(wrapper< A<T> >) 
{} 


int main() 
{ 
    foo( wrapper<void>{}); 
} 

错误消息:

t.cpp:24:7: error: no matching function for call to 'foo' 
     foo( wrapper<void>{}); 
     ^~~ 
t.cpp:18:10: note: candidate template ignored: could not match 'A<type-parameter-0-0>' against 'void' 
    void foo(wrapper< A<T> >) 
     ^
1 error generated. 

,以及如何解决它?

我预计wrapper<void>被铸造到wrapper< A<void >使用演员运算符class wrapper

int main() 
{ 
    foo(static_cast< wrapper< A<void> > >(wrapper<void>{})); 
} 

其中编译顺利:使用static_cast作为显示在下面的

+1

要修复它执行显式的静态转换,所以模板参数的扣除会得到正确的类型。您似乎认为模板参数扣除会考虑可能的用户定义转换。 – VTT

回答

3

问题是foo -s模板演绎失败,因为隐式转换。

  • foo尝试推算T型
  • P = wrapper<void>,A = wrapper<A<T>>
  • foo没有可能的方式来推断出A<T>

所以,我们必须帮助foo推断ŧ 。

解决方案1 ​​

foo知道什么为T明确:

foo<void>(wrapper<void>{}); 

解决方案2

演员wrapperwrapper< A<void> >明确,让foo知道什么T是:

foo(static_cast< wrapper< A<void> > >(wrapper<void>{})); 
+0

问题是为什么扣除失败?它适用于template 以及void foo(包装器)? – DrSvanHay

3

你可以明确地修复它投wrapper<void>wrapper< A<void> >


请注意,模板扣除尝试完全匹配模板参数而不进行转换。这意味着如果为了使事情完全匹配而需要演员阵容,演员阵容必须是明确的。