尽管定义了强制转换运算符,但没有强制转换

No cast although cast operator is defined

谁能帮我理解为什么以下代码无法编译:

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.

如何解决?

我希望使用 class wrapper 的转换运算符将 wrapper<void> 转换为 wrapper< A<void >

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

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

编译顺利


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

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

  • foo 尝试推导类型 T
  • P=wrapper<void>,A=wrapper<A<T>>
  • foo 无法推断出 A<T> 是什么

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

解决方案 1

foo明确知道T是什么:

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

解决方案 2

明确地将 wrapper 转换为 wrapper< A<void> > 以让 foo 知道 T 是什么:

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