|
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