【问题标题】:No cast although cast operator is defined尽管定义了强制转换运算符,但没有强制转换
【发布时间】:2018-03-15 17:39:25
【问题描述】:

谁能帮我理解为什么下面的代码不能编译:

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&lt;void&gt; 使用 class wrapper 的转换运算符转换为 wrapper&lt; A&lt;void &gt;

【问题讨论】:

  • 修复它执行显式静态强制转换,因此模板参数推导将获得正确的类型。您似乎假设模板参数扣除将考虑可能的用户定义的转换。

标签: c++ templates casting typecast-operator


【解决方案1】:

您可以通过使用static_castwrapper&lt; void &gt; 显式转换为wrapper&lt; A&lt;void&gt; &gt; 来修复它,如下所示:

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

编译顺利。


请注意,模板推导确实会尝试完全匹配模板参数而不进行转换。这意味着如果为了使事情完全匹配而需要强制转换,那么强制转换必须是显式的。

【讨论】:

    【解决方案2】:

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

    • foo 尝试推断类型 T
    • P = wrapper&lt;void&gt;,A = wrapper&lt;A&lt;T&gt;&gt;
    • foo 无法推断出A&lt;T&gt; 是什么

    所以,我们必须帮助foo推导出T。

    解决方案 1

    foo 明确知道什么是 T:

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

    解决方案 2

    wrapper 明确转换为wrapper&lt; A&lt;void&gt; &gt; 以让foo 知道T 是什么:

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

    【讨论】:

    • 问题是为什么扣除失败?它适用于 template 以及 void foo( wrapper ) ?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 2021-05-28
    • 2011-01-20
    相关资源
    最近更新 更多