http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55460



             Bug #: 55460

           Summary: Template-dependent name is not looked up at

                    instantiation point

    Classification: Unclassified

           Product: gcc

           Version: 4.6.1

            Status: UNCONFIRMED

          Severity: normal

          Priority: P3

         Component: c++

        AssignedTo: unassig...@gcc.gnu.org

        ReportedBy: solo...@mail.com





Created attachment 28768

  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=28768

Code reproducing bug



Howdy,



I think this is a bug in G++. I have a call to a template function filter(T) in

a template context. filter() is further overloaded before the instantiation

point. G++ 4.6.1 and 4.5.2 (both under MinGW, sorry, I don't have access to a

more recent version) seems to resolve it at declaration point (see attachment

for the exact code reproducing bug):



namespace my

{

    ...

    // A function template that by default behaves as identity

    template <typename P>

    typename std::remove_reference<P>::type 

    filter(P&& p) throw() { return std::move(p); }

    ...

} // of namespace my 



// Since this is unrestricted template, ADL won't work, so we have to stick 

// this overloaded operator building an expression template into the global

scope

template <typename P1>

inline auto operator&(P1&& p1) throw()

        -> typename std::enable_if<

                        my::is_mine<P1>::value,

                        my::address<decltype(my::filter(std::forward<P1>(p1)))>

                    >::type

{

    // NOTE: call to filter depends on template argument, thus have to be

    //       resolved at instantiation point. But it doesn't!

    return my::address<decltype(my::filter(std::forward<P1>(p1)))>

                               (my::filter(std::forward<P1>(p1)));

}



// We now declare few more classes modeling our concept: var and ref

namespace my

{

    template <typename T> class var;

    template <typename T> class ref;

    ...

    // and specialize function filter on them

    template <typename T> inline ref<var<T>>   filter( var<T>& t) throw() 

    { return ref<var<T>>(t); }

} // of namespace my 



int main()

{

    my::var<int> h;

    auto&& a = &h;  // Instantiate expression template via overloaded operator&

    std::cout << typeid(a).name() << std::endl;

}



GCC 4.6.1 output is:



    N2my7addressINS_3varIiEEEE



which indicates that there is no ref<> applied to var<> in instantiation of

address<>. Visual C++ 10 and 11 produce:



    struct my::address<struct my::ref<struct my::var<int> > >



which have ref<> in between and is what I was actually expecting to have.



If I move the definition of overloaded operator& after the second namespace my

is closed, the ref<> does properly appear on top of the var<>.



Can you please have a look at this?

Thank you!

Reply via email to