
Brian McNamara <lorgon@cc.gatech.edu> writes:
On Thu, Feb 19, 2004 at 11:35:13PM -0500, David Abrahams wrote:
Brian McNamara <lorgon@cc.gatech.edu> 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