abraham_hilbert
abraham_hilbert

Reputation: 2271

No cast although cast operator is defined

Can someone please help me to understand why the following code does not compile:

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>{} );
}

error message:

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.

and how to fix it?

I expected that wrapper<void> is casted to wrapper< A<void > using the cast operator of class wrapper.

Upvotes: 2

Views: 140

Answers (2)

Daniel Trugman
Daniel Trugman

Reputation: 8501

The problem is that foo-s template deduction fails because the of the implicit cast.

  • foo tries to deduce type T
  • P = wrapper<void>, A = wrapper<A<T>>
  • foo has no possible way to deduce what A<T> is

So, we have to help foo deduce T.

Solution 1

Let foo know what is T explicitly:

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

Solution 2

Cast wrapper to wrapper< A<void> > explicitly to let foo know what T is:

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

Upvotes: 3

Davide Spataro
Davide Spataro

Reputation: 7482

You can fix it by explicitly cast wrapper< void > to wrapper< A<void> > using static_cast as shown in the following:

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

which compiles smoothly.


Note that template deduction does try to match the template parameters exactly without doing conversions. It means that if a cast is necessary in order to make things match exactly then the cast has to be explicit.

Upvotes: 3

Related Questions