Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2004-02-20 12:25:49


Brian McNamara <lorgon_at_[hidden]> writes:

> On Thu, Feb 19, 2004 at 11:35:13PM -0500, David Abrahams wrote:
>> Brian McNamara <lorgon_at_[hidden]> writes:
>> > On Thu, Feb 19, 2004 at 04:54:36PM -0500, David Abrahams wrote:
> ...
>> >> // user.cpp
>> >> #include "lib.hpp"
>> >> #include "user.hpp" // defines some user::f overload
>> >>
>> >> int main()
>> >> {
>> >> user::my_class x;
>> >> lib::g(x); // calls user::f()
>> >> }
>> >
>> > The return of name-capture... I dunno enough about the standard to know
>> > if this is a bug or not. I am curious what you mean by "when ADL is
>> > disabled with parentheses": surely ADL is still needed for lib::g to
>> > call user::f?
>>
>> Ugh, of course. Sorry, I should've said:
>>
>> lib::g(x); // calls lib::f(user::my_class)
>
> And
> #include "user.hpp" // defines some user::f overload
> should be
> #include "user.hpp" // defines some lib::f overload
> ? Just checking; I think yes.
>

Yes. Sorry again.

>> > I have seen parens around function names before as a
>> > means to something, but can you give me the reminder-summary of what
>> > the parens do?
>>
>> They disable ADL.
>
> Neat!

Well, ugly IMO. I can understand why it'd appeal to someone who
usually invokes f this way, though:

        f x y z

;-)

>> > (Despite the fact that no one wants to hear it, I would feel remiss if I
>> > didn't play Chicken Little and say "Fool's gold! Qualified calls and
>> > template specialization are the one true path to such customization!
>>
>> You'd be wrong. It'd be nice if it were true, but qualified calls
>> are subject to order dependencies, among other problems.
>
> I'm not clear about this.
>
> // lib.hpp
> namespace lib {
> template <class T> void f(T);
> template <class T> void g(T x) { lib::f(x); }
> }
>
> // user.hpp
> #include "lib.hpp"
> namespace user {
> struct MyClass {};
> }
> namespace lib {
> template <> void f( user::MyClass ) { /* print "foo" */ }
Not an overload.

> }
>
> // user.cpp
> #include "user.hpp"
> int main() {
> user::MyClass m;
> lib::g(m);
> }
>
> Would that not print "foo"? What is the order dependency?

That's a specialization. Actually, there'd still be an order
dependency if g wasn't a function template, but that's beside the
point.

   // lib.hpp
   namespace lib {
      template <class T> void f(T);
      template <class T> void g(T x) { lib::f(x); }
   }
   
   // user.hpp
   #include "lib.hpp"
   namespace user {
      struct MyClass {};
   }
   namespace lib {
      void f( user::MyClass ) { /* print "foo" */ } // AN OVERLOAD
   }
      
   // user.cpp
   #include "user.hpp"
   int main() {
      user::MyClass m;
      lib::g(m); // link error; no body for f<T> where T = user::MyClass.
   }
   

> (I don't
> think I have access to a compiler that supposedly does this right, or
> else I'd try it myself.) What are the other problems? (I know one:
> function templates can't be "partially" specialized, which means you
> sometimes need to use a class helper, ugh.)

specialization interacts badly with overloading too:

  template <class T> int f(T);
  template <> int f(int*);
  template <class T> void f(T*);

  int x = 0;
  int y = f(&x); // error; can't convert void to int.
  

> (Apologies if this is a topic we've discussed before.)

See LWG 225,226,229, and the qn paper I referenced earlier.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk