Template argument deduction and conversion operators.

Discussion in 'C++' started by BigMan@abv.bg, Feb 2, 2005.

  1. Guest

    Here is a piece of code:

    #include <memory>
    using namespace std;

    template< typename SomeType >
    void f(auto_ptr_ref< SomeType >)
    {
    }

    int __cdecl main(int,char*[])
    {
    auto_ptr< int > a;
    f( a ); // 1: could not deduce template argument
    f< int >( a ); // 2: OK
    return 0;
    }

    My question is if there is a standard way to force the compiler to
    compile line 1 as it compiles line 2, i.e. to deduce template arguments
    in a way that will allow conversion operators to be called if
    necessary.
     
    , Feb 2, 2005
    #1
    1. Advertising

  2. wrote:
    > Here is a piece of code:
    >
    > #include <memory>
    > using namespace std;
    >
    > template< typename SomeType >
    > void f(auto_ptr_ref< SomeType >)
    > {
    > }
    >
    > int __cdecl main(int,char*[])
    > {
    > auto_ptr< int > a;
    > f( a ); // 1: could not deduce template argument
    > f< int >( a ); // 2: OK
    > return 0;
    > }
    >
    > My question is if there is a standard way to force the compiler to
    > compile line 1 as it compiles line 2, i.e. to deduce template arguments
    > in a way that will allow conversion operators to be called if
    > necessary.


    No. The rule is that the conversions are not applied when trying to
    deduce template arguments. There are several (although quite a few)
    context in which the argument is deducible, and none of them involve
    conversions, IIRC.

    V
     
    Victor Bazarov, Feb 2, 2005
    #2
    1. Advertising

  3. wrote:
    > Here is a piece of code:
    >
    > #include <memory>
    > using namespace std;
    >
    > template< typename SomeType >
    > void f(auto_ptr_ref< SomeType >)
    > {
    > }
    >
    > int __cdecl main(int,char*[])
    > {
    > auto_ptr< int > a;
    > f( a ); // 1: could not deduce template argument
    > f< int >( a ); // 2: OK
    > return 0;
    > }
    >
    > My question is if there is a standard way to force the compiler to
    > compile line 1 as it compiles line 2, i.e. to deduce template arguments
    > in a way that will allow conversion operators to be called if
    > necessary.


    Of course not. We can even forget about the rules of template argument
    deduction. It is impossible for a more generic reason.

    The conversion operator that converts 'auto_ptr<T>' to
    'auto_ptr<T>::auto_ptr_ref<U>' is itself a template with its own
    independent parameter (note 'U'). This means that the above conversion
    is infinitely ambiguous. How do you expect the compiler to treat the
    line 1? As

    f<int>(a.operator auto_ptr_ref<int>());

    ? Why not

    f<double>(a.operator auto_ptr_ref<double>());

    or

    f<char>(a.operator auto_ptr_ref<char>());

    Note, once again, that the parameter of the conversion operator template
    is not related in any way to the parameter of the entire 'auto_ptr<>'
    class template, which means that from the compiler's point of view the
    first variant (with 'int') is in no way better than any other variant.
    (It's like solving an equation with two unknowns. In general case it has
    infinite number of solutions and no one is better than the others.)

    In order to resolve the ambiguity in one way of another you have to
    provide compiler with extra information. On way to do it is to specify
    the 'f' template argument explicitly and let the compiler to deduce the
    argument for the conversion operator

    f<int>(a);

    Another way would be to perform explicit type conversion and let the
    compiler to deduce 'f's template argument

    f((auto_ptr<int>::auto_ptr_ref<int>) a);

    The last example is provided for purely illustrational purposes, it will
    not work in practice because 'auto_ptr_ref' is not a public member of
    'auto_ptr'.

    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Feb 2, 2005
    #3
  4. Guest

    Yes, you are right that in the case with auto_ptr and auto_ptr_ref the
    call is ambiguous! And all this is due to the templated conversion
    operator.
    Now, could you consider my previous question in the case where the
    conversion operator is not templated as in the code that follows. My
    question was: is it possible to deduce templat­e arguments in a way
    that will allow conversion operators to be called i­f necessary?

    template< typename SomeType >
    class RW;

    template< typename SomeType >
    class RWRef
    {
    private:
    RWRef( RW< SomeType > const* const ){ }
    friend RW< SomeType >;
    };

    template< typename SomeType >
    class RW
    {
    public:
    RW( ) { }

    operator RWRef< SomeType >( ) const { return RWRef< SomeType >( this
    ); }
    };

    template< typename SomeType >
    void f
    (
    RWRef< SomeType >
    )
    {
    }

    int main
    (
    int,
    char*[]
    )
    {
    RW< int > a;
    f( a );

    return 0;
    }
     
    , Feb 2, 2005
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Peng Yu

    Template argument deduction

    Peng Yu, Apr 16, 2005, in forum: C++
    Replies:
    1
    Views:
    509
    Mike Wahler
    Apr 16, 2005
  2. Bart Samwel
    Replies:
    14
    Views:
    811
    Bart Samwel
    Apr 22, 2005
  3. George
    Replies:
    4
    Views:
    412
    George
    Jan 13, 2006
  4. ma740988

    template argument deduction

    ma740988, May 29, 2006, in forum: C++
    Replies:
    5
    Views:
    1,457
    Bo Persson
    May 29, 2006
  5. Tobias Müller
    Replies:
    12
    Views:
    501
    Nobody
    Dec 15, 2011
Loading...

Share This Page