
Hi Everyone, I've encountered a problem with MSVC which I have no idea how to go around with regards to using extern placeholders for template method type deductions. Let me give an example: template <class T> struct some_type { }; struct a_type { } ; extern a_type placeholder ; template <class T> some_type<T> method(T) { return some_type<T>(); }; // ... { method(placeholder); } The code works (compiles fine) in GCC -- it doesn't bother looking for the placeholder during link time. However MSVC 8 throws a fit and doesn't want to link the executable because it keeps looking for the implementation of placeholder -- where the code obviously doesn't require linking to it in any way, except for the purposes of type deduction in the template method. Am I encountering an MSVC bug? Is there a better way of going about this? Insights would be most appreciated. Thanks in advance! -- Dean Michael C. Berris http://cplusplus-soup.blogspot.com/ mikhailberis AT gmail DOT com +63 928 7291459

Hi Everyone,
I've encountered a problem with MSVC which I have no idea how to go around with regards to using extern placeholders for template method type deductions. Let me give an example:
template <class T> struct some_type { };
struct a_type { } ;
extern a_type placeholder ;
template <class T> some_type<T> method(T) { return some_type<T>(); };
// ... { method(placeholder); }
The code works (compiles fine) in GCC -- it doesn't bother looking for the placeholder during link time. However MSVC 8 throws a fit and doesn't want to link the executable because it keeps looking for the implementation of placeholder -- where the code obviously doesn't require linking to it in any way, except for the purposes of type deduction in the template method.
Am I encountering an MSVC bug? I don't think so. The call: method(placeholder); is "potentially evaluated" and hence the name "placeholder" is "used" (see 3.2/2 of the standard) and 3.2/3 says: "Every program shall contain exactly one definition of every non-inline function or object that is used in that
----Original Message---- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Dean Michael Berris Sent: 06 July 2007 08:00 To: boost@lists.boost.org Subject: [boost] extern placeholders and MSVC 8 program; no diagnostic required."
Is there a better way of going about this?
I think we need more background. Options: - Define 'placeholder' - Change the declarations to extern a_type* placeholder (and define placeholder to null somewhere). some_type<T> method(T*) { return some_type<T>(); }; - Make 'method' take no arguments and explicit specify the template arguments. - Something else.
Insights would be most appreciated.
Thanks in advance!
-- Martin Bonner Project Leader PI SHURLOK LTD Telephone: +44 1223 441434 / 203894 (direct) Fax: +44 1223 203999 Email: martin.bonner@pi-shurlok.com www.pi-shurlok.com disclaimer

Ei Martin! On 7/6/07, Martin Bonner <Martin.Bonner@pi-shurlok.com> wrote:
I don't think so. The call: method(placeholder); is "potentially evaluated" and hence the name "placeholder" is "used" (see 3.2/2 of the standard) and 3.2/3 says: "Every program shall contain exactly one definition of every non-inline function or object that is used in that program; no diagnostic required."
Wow, hmmm... Okay. I don't think I understand why MSVC isn't "smart enough" to figure that 'placeholder' is just being used or linked to anywhere in the program except for type deduction while GCC (4.1.2) deals with this quite "intelligently".
Is there a better way of going about this?
I think we need more background. Options: - Define 'placeholder' - Change the declarations to extern a_type* placeholder (and define placeholder to null somewhere). some_type<T> method(T*) { return some_type<T>(); }; - Make 'method' take no arguments and explicit specify the template arguments. - Something else.
As for background, I'm trying to achieve what Boost.Bind does with: boost::bind(&function, _1, _2) -- where _1 and _2 are used mainly as placeholders -- without having to resort to unnamed namespaces (namespace { ... }) to avoid ODR violation. I'm looking at doing something (for the network library I'm working on): network::message m; m << transform(to_upper_, headers_); In the above, to_upper_ and headers_ are placeholders which are used mainly for type deduction -- while transform returns an instance of a type (a functor) with template parameters dependent on the types of to_upper_ and headers_. I've been successful with using extern placeholders in GCC, and during link time I don't encounter the errors which I encounter with MSVC. I now need to find a way of doing this another way. Any ideas? Thanks for the clarifications. -- Dean Michael C. Berris http://cplusplus-soup.blogspot.com/ mikhailberis AT gmail DOT com +63 928 7291459

----- Mensaje original ----- De: Dean Michael Berris <mikhailberis@gmail.com> Fecha: Sábado, Julio 7, 2007 9:17 am Asunto: Re: [boost] extern placeholders and MSVC 8 Para: boost@lists.boost.org [...]
As for background, I'm trying to achieve what Boost.Bind does with: boost::bind(&function, _1, _2) -- where _1 and _2 are used mainly as placeholders -- without having to resort to unnamed namespaces (namespace { ... }) to avoid ODR violation. I'm looking at doing something (for the network library I'm working on):
network::message m; m << transform(to_upper_, headers_);
In the above, to_upper_ and headers_ are placeholders which are used mainly for type deduction -- while transform returns an instance of a type (a functor) with template parameters dependent on the types of to_upper_ and headers_.
If you're using the placeholders exclusively as syntactic tokens, then the following ODR-abiding technique can be of use: http://lists.boost.org/Archives/boost/2006/07/108355.php On why this technique cannot be used for more advanced placeholders such as those of Boost.Lambda, see: http://lists.boost.org/Archives/boost/2007/06/123375.php http://lists.boost.org/Archives/boost/2007/06/123376.php HTH, Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

"JOAQUIN LOPEZ MU?Z" wrote:
----- Mensaje original ----- De: Dean Michael Berris <mikhailberis@gmail.com> Fecha: Sábado, Julio 7, 2007 9:17 am Asunto: Re: [boost] extern placeholders and MSVC 8 Para: boost@lists.boost.org
[...]
As for background, I'm trying to achieve what Boost.Bind does with: boost::bind(&function, _1, _2) -- where _1 and _2 are used mainly as placeholders -- without having to resort to unnamed namespaces (namespace { ... }) to avoid ODR violation. I'm looking at doing something (for the network library I'm working on):
network::message m; m << transform(to_upper_, headers_);
In the above, to_upper_ and headers_ are placeholders which are used mainly for type deduction -- while transform returns an instance of a type (a functor) with template parameters dependent on the types of to_upper_ and headers_.
If you're using the placeholders exclusively as syntactic tokens, then the following ODR-abiding technique can be of use:
enum to_upper_placeholder { to_upper_ }; is easier if you don't mind the conversion to int. The inline function technique was first suggested to me by Yitzhak Sapir, FWIW. http://aspn.activestate.com/ASPN/Mail/Message/boost/1157287

Hi Peter! On 7/7/07, Peter Dimov <pdimov@mmltd.net> wrote:
"JOAQUIN LOPEZ MU?Z" wrote:
If you're using the placeholders exclusively as syntactic tokens, then the following ODR-abiding technique can be of use:
enum to_upper_placeholder { to_upper_ };
is easier if you don't mind the conversion to int.
I actually mind the conversion to int... I've actually thought about doing this before if all else failed.
The inline function technique was first suggested to me by Yitzhak Sapir, FWIW.
Thanks for the link! -- Dean Michael C. Berris http://cplusplus-soup.blogspot.com/ mikhailberis AT gmail DOT com +63 928 7291459

Hi Joaquin! On 7/7/07, "JOAQUIN LOPEZ MU?Z" <joaquin@tid.es> wrote:
----- Mensaje original ----- De: Dean Michael Berris <mikhailberis@gmail.com> Fecha: Sábado, Julio 7, 2007 9:17 am Asunto: Re: [boost] extern placeholders and MSVC 8 Para: boost@lists.boost.org
[...]
As for background, I'm trying to achieve what Boost.Bind does with: boost::bind(&function, _1, _2) -- where _1 and _2 are used mainly as placeholders -- without having to resort to unnamed namespaces (namespace { ... }) to avoid ODR violation. I'm looking at doing something (for the network library I'm working on):
network::message m; m << transform(to_upper_, headers_);
In the above, to_upper_ and headers_ are placeholders which are used mainly for type deduction -- while transform returns an instance of a type (a functor) with template parameters dependent on the types of to_upper_ and headers_.
If you're using the placeholders exclusively as syntactic tokens, then the following ODR-abiding technique can be of use:
Nice! That clears things up a lot! :-)
On why this technique cannot be used for more advanced placeholders such as those of Boost.Lambda, see:
http://lists.boost.org/Archives/boost/2007/06/123375.php http://lists.boost.org/Archives/boost/2007/06/123376.php
Thanks for the links!
HTH,
They definitely do. :) Thank you again! -- Dean Michael C. Berris http://cplusplus-soup.blogspot.com/ mikhailberis AT gmail DOT com +63 928 7291459

From: Dean Michael Berris
As for background, I'm trying to achieve what Boost.Bind does with: boost::bind(&function, _1, _2) -- where _1 and _2 are used mainly as placeholders -- without having to resort to unnamed namespaces (namespace { ... }) to avoid ODR violation. I'm looking at doing something (for the network library I'm working on):
network::message m; m << transform(to_upper_, headers_);
In the above, to_upper_ and headers_ are placeholders which are used mainly for type deduction -- while transform returns an instance of a type (a functor) with template parameters dependent on the types of to_upper_ and headers_.
I've been successful with using extern placeholders in GCC, and during link time I don't encounter the errors which I encounter with MSVC. I now need to find a way of doing this another way.
I assume current declarations like: extern to_upper_t to_upper_; extern headers_t headers_; template<T1,T2> transform(T1 t1, T2 t2); - The simple one is: m << transform<to_upper_t,headers_t>(); - You could add a CPP where you define all the externals. There must be other options. -- Martin Bonner Project Leader PI SHURLOK LTD Telephone: +44 1223 441434 / 203894 (direct) Fax: +44 1223 203999 Email: martin.bonner@pi-shurlok.com www.pi-shurlok.com disclaimer
participants (4)
-
"JOAQUIN LOPEZ MU?Z"
-
Dean Michael Berris
-
Martin Bonner
-
Peter Dimov