public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/55460] New: Template-dependent name is not looked up at instantiation point
@ 2012-11-25  0:38 solodon at mail dot com
  2012-11-25  0:49 ` [Bug c++/55460] " pinskia at gcc dot gnu.org
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: solodon at mail dot com @ 2012-11-25  0:38 UTC (permalink / raw)
  To: gcc-bugs


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: unassigned@gcc.gnu.org
        ReportedBy: solodon@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!


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2012-11-25 20:46 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-11-25  0:38 [Bug c++/55460] New: Template-dependent name is not looked up at instantiation point solodon at mail dot com
2012-11-25  0:49 ` [Bug c++/55460] " pinskia at gcc dot gnu.org
2012-11-25  1:07 ` solodon at mail dot com
2012-11-25  1:56 ` pinskia at gcc dot gnu.org
2012-11-25 20:46 ` redi at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).