mardi 24 novembre 2015

Automatic deducing of the type that should be returned by operator or function

What is the purpose of very peculiar behaviour of conversion operator template? Consider the following code:

#include <iostream>
#include <utility>

#include <cstdlib>

#define PP { std::cout << __PRETTY_FUNCTION__ << std::endl; }

struct A
{
    template< typename T >
    operator T () { PP; return {}; }
    template< template< typename ... > class C, typename ...types >
    operator C< types... > () { PP; return {}; }
    template< typename T >
    T operator * () { PP; return {}; }
};

static void f(int) PP

template< typename T >
struct S {};

template< typename T = void >
void g(S< T >) PP

int main()
{
    struct B {};

    // T A::operator B() [T = B]
    B{} = A{};

    // C<types...> A::operator S() [C = S, types = <void>]
    S< void >{} = A{};

    // T A::operator int() [T = int]
    // void f(int)
    f(A{});

    // void g(S<T>) [T = void]
    g({});

    // expected the same output prepended by "T A::operator int() [T = S<void>]"
    // but conversion operator does not involved after first step when matching failed
    // and default value of template parameter should be chosen to next try
    // error: no matching function for call to 'g'
    // note: candidate template ignored: could not match 'S<type-parameter-0-0>' against 'A'
    //g(A{});

    // error: indirection requires pointer operand ('A' invalid)
    //B{} = *A{};

    // error: no matching member function for call to 'operator*'
    // note: candidate template ignored: couldn't infer template argument 'T'
    //B{} = A{}.operator * ();

    // error: indirection requires pointer operand ('A' invalid)
    //(*A{}).~A();
    return EXIT_SUCCESS;
}

Its ability to automatically deduce a returning type required by recepient (left hand side of assignment expression or actual function argument type) is unique as far as I can see. I can't reproduce such behaviour for unary operator *, operator ->, operator () and others.

Aucun commentaire:

Enregistrer un commentaire