boost and vendor's TR1 implementations

Hello All, Today there is at least two implementations of TR1 library extensions shipped with compilers. I mean VS 2008 SP1 and gcc 4.3.x STL. Because of boost has it's own implementation of TR1 there is some problems with migrating code to this compilers. For example: 1. There is many ambiguous names if both boost and std::tr1 exposed into global namespace. 2. boost::transform_iterator knows nothing about std::tr1::bind shipped with VS2008 compiler. I think what first problem is very serious. I sure what there is a lot of code what exposed 'boost' namespace into global scope. Some of boost test cases has such directives (tests for 'function', 'tokenizer', 'string algo' libraries for example). When developers will start to expose 'std::tr1' namespace into global scope they will be encountered many problems with compilation. I think what it will be good idea to hide boost implementation of TR1 classes when this classes shipped with compiler. For example: //... #ifdef _HAS_TR1 #include <memory> namespace boost { using std::tr1::shared_ptr; //... other usings } #else // rest of the shared_ptr.hpp #endif -- Best Regards, Sergey mailto:flex_ferrum@artberg.ru

Sergey Sadovnikov wrote:
Hello All,
Today there is at least two implementations of TR1 library extensions shipped with compilers. I mean VS 2008 SP1 and gcc 4.3.x STL. Because of boost has it's own implementation of TR1 there is some problems with migrating code to this compilers. For example:
1. There is many ambiguous names if both boost and std::tr1 exposed into global namespace. 2. boost::transform_iterator knows nothing about std::tr1::bind shipped with VS2008 compiler.
I think what first problem is very serious. I sure what there is a lot of code what exposed 'boost' namespace into global scope. Some of boost test cases has such directives (tests for 'function', 'tokenizer', 'string algo' libraries for example). When developers will start to expose 'std::tr1' namespace into global scope they will be encountered many problems with compilation. I think what it will be good idea to hide boost implementation of TR1 classes when this classes shipped with compiler. For example:
//... #ifdef _HAS_TR1 #include <memory>
namespace boost { using std::tr1::shared_ptr; //... other usings } #else // rest of the shared_ptr.hpp #endif
Many of the boost libraries have evolved beyond their TR1 counter parts. Boost's shared_ptr is a good example of this. I primarily use VC9 SP1 which has a tr1 implementation but I use features of boost::shared_ptr that std::tr1::shared_ptr doesn't have. -- Michael Marcin

Hello, Michael. Tuesday, November 11, 2008 at 10:43:38 PM you wrote: MM> Sergey Sadovnikov wrote: MM> Many of the boost libraries have evolved beyond their TR1 counter parts. MM> Boost's shared_ptr is a good example of this. I primarily use VC9 SP1 MM> which has a tr1 implementation but I use features of boost::shared_ptr MM> that std::tr1::shared_ptr doesn't have. Do you mean what there is no way to make boost and TR1 implementations don't conflict each other? And, for example, boost::shared_ptr couldn't be transparently replaced by corresponding TR1 class? -- Best Regards, Sergey mailto:flex_ferrum@artberg.ru

Sergey Sadovnikov wrote:
Hello, Michael.
Tuesday, November 11, 2008 at 10:43:38 PM you wrote:
MM> Sergey Sadovnikov wrote:
MM> Many of the boost libraries have evolved beyond their TR1 counter parts. MM> Boost's shared_ptr is a good example of this. I primarily use VC9 SP1 MM> which has a tr1 implementation but I use features of boost::shared_ptr MM> that std::tr1::shared_ptr doesn't have.
Do you mean what there is no way to make boost and TR1 implementations don't conflict each other? And, for example, boost::shared_ptr couldn't be transparently replaced by corresponding TR1 class?
Correct, TR1 shared_ptr doesn't support boost::make_shared for instance. -- Michael Marcin

Hello, Michael. Tuesday, November 11, 2008 at 11:09:03 PM you wrote: MM> Sergey Sadovnikov wrote:
Do you mean what there is no way to make boost and TR1 implementations don't conflict each other? And, for example, boost::shared_ptr couldn't be transparently replaced by corresponding TR1 class?
MM> Correct, TR1 shared_ptr doesn't support boost::make_shared for instance.
Hm. How I can see, boost::make_shared doesn't demand from shared_ptr class something special which not covered by TR1 specification. So I can replace explicit implementation of boost::shared_ptr with 'using std::tr1::shared_ptr' directive. Am I right? -- Best Regards, Sergey mailto:flex_ferrum@artberg.ru

Sergey Sadovnikov wrote:
Hello, Michael.
Tuesday, November 11, 2008 at 11:09:03 PM you wrote:
MM> Sergey Sadovnikov wrote:
Do you mean what there is no way to make boost and TR1 implementations don't conflict each other? And, for example, boost::shared_ptr couldn't be transparently replaced by corresponding TR1 class?
MM> Correct, TR1 shared_ptr doesn't support boost::make_shared for instance.
Hm. How I can see, boost::make_shared doesn't demand from shared_ptr class something special which not covered by TR1 specification. So I can replace explicit implementation of boost::shared_ptr with 'using std::tr1::shared_ptr' directive. Am I right?
I'm pretty sure make_shared relies on implementation details of boost::shared_ptr. Also I IIRC boost::shared_ptr's aliasing constructor isn't in std::tr1::shared_ptr. There are other reasons that you might want to use the boost versions over the tr1 versions. For instance the boost unordered containers are supposedly faster than the vc9sp1 tr1 implementation and the vc9sp1 tr1::function has a broken swap which prevents it from being used in the std::containers because of the "Swaptimization". -- Michael Marcin

Hello, Michael. Wednesday, November 12, 2008 at 12:03:41 AM you wrote: MM> I'm pretty sure make_shared relies on implementation details of MM> boost::shared_ptr. Also I IIRC boost::shared_ptr's aliasing constructor MM> isn't in std::tr1::shared_ptr. MM> There are other reasons that you might want to use the boost versions MM> over the tr1 versions. For instance the boost unordered containers are MM> supposedly faster than the vc9sp1 tr1 implementation and the vc9sp1 MM> tr1::function has a broken swap which prevents it from being used in the MM> std::containers because of the "Swaptimization". By the way when C++0x will be committed and std::tr1 namespace will be merged with std namespace a lot of code will become uncompilable because of both std and boost namespaces exposed into global or local scope. ACSoft wrote into boost-users mailing list: ----------------------------------------------- Either way, as soon as people start to use c++0x compiler and c++0x-conform stl implementations (in fact a lot of people already do - like me), all the old code that uses using namespace std and using namespace boost will fail to compile (the tr1 stuff is merged into std in c++0x - and a lot of these old tr1 libraries are included indirectly by other stl headers!). As boost and the stl are fundamental libraries, they should, in my opinion, coexist in the global namespace. I think the boost implementations should move the std::tr1 implementation into the boost namespace if possible. This should solve all the problems. ----------------------------------------------- -- Best Regards, Sergey mailto:flex_ferrum@artberg.ru

On Wed, Nov 12, 2008 at 11:32:39AM +0300, Sergey Sadovnikov wrote:
By the way when C++0x will be committed and std::tr1 namespace will be merged with std namespace a lot of code will become uncompilable because of both std and boost namespaces exposed into global or local scope.
IMHO that's why namespace was invented, and why using-directive is not recommended, if not forbidden.

on Wed Nov 12 2008, Sergey Sadovnikov <flex_ferrum-AT-artberg.ru> wrote:
By the way when C++0x will be committed and std::tr1 namespace will be merged with std namespace a lot of code will become uncompilable because of both std and boost namespaces exposed into global or local scope.
"Doctor, it hurts when I do this..." Sorry to be glib, but I really can't get too worked up over this. This is why we have namespaces. If you erase the namespace boundaries, collisions happen. Should anyone be surprised that names in Boost, a library collection specifically aimed at standardization, eventually match some of those in std::? -- Dave Abrahams BoostPro Computing http://www.boostpro.com

David Abrahams wrote:
on Wed Nov 12 2008, Sergey Sadovnikov <flex_ferrum-AT-artberg.ru> wrote:
By the way when C++0x will be committed and std::tr1 namespace will be merged with std namespace a lot of code will become uncompilable because of both std and boost namespaces exposed into global or local scope.
"Doctor, it hurts when I do this..."
Sorry to be glib, but I really can't get too worked up over this. This is why we have namespaces. If you erase the namespace boundaries, collisions happen. Should anyone be surprised that names in Boost, a library collection specifically aimed at standardization, eventually match some of those in std::?
And anyway, you don't get problems unless you're actually using one of the types that are now ambiguous. That is, you don't get an error just because you have using namespace boost and using namespace std in the same file. You only get an error if you then attempt to use shared_ptr without qualification. Which is still a problem that probably affects quite a bit of code, but much less. Sebastian

Hello, David. Wednesday, November 12, 2008 at 8:14:55 PM you wrote: DA> on Wed Nov 12 2008, Sergey Sadovnikov <flex_ferrum-AT-artberg.ru> wrote:
By the way when C++0x will be committed and std::tr1 namespace will be merged with std namespace a lot of code will become uncompilable because of both std and boost namespaces exposed into global or local scope.
DA> "Doctor, it hurts when I do this..." :) DA> Sorry to be glib, but I really can't get too worked up over this. DA> This is why we have namespaces. If you erase the namespace boundaries, DA> collisions happen. Should anyone be surprised that names in Boost, a DA> library collection specifically aimed at standardization, eventually DA> match some of those in std::? Absolutely right, but... Let's see an example. Just get the one of the boost test cases (http://www.boost.org/doc/libs/1_37_0/libs/function/test/lambda_test.cpp) and try to compile with gcc 4.3.2: ----------------------------------------------------------------------- // Boost.Function library // Copyright Douglas Gregor 2002-2003. Use, modification and // distribution is subject to the Boost Software License, Version // 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // For more information, see http://www.boost.org #include <iostream> #include <cstdlib> #include <boost/test/minimal.hpp> #include <boost/lambda/lambda.hpp> #include <boost/lambda/bind.hpp> #include <boost/function.hpp> using namespace std; using namespace boost; using namespace boost::lambda; static unsigned func_impl(int arg1, bool arg2, double arg3) { return abs (static_cast<int>((arg2 ? arg1 : 2 * arg1) * arg3)); } int test_main(int, char*[]) { function <unsigned(bool, double)> f1 = bind(func_impl, 15, _1, _2); function <unsigned(double)> f2 = bind(f1, false, _1); function <unsigned()> f3 = bind(f2, 4.0); f3(); return 0; } ----------------------------------------------------------------------- Compiler says: P:\projects\Tests\Sandbox\C++0x\gcc43>g++ -std=c++0x -IP:\projects\common\boost_1.36.0 boost_test1.cpp boost_test1.cpp: In function 'int test_main(int, char**)': boost_test1.cpp:30: error: reference to 'function' is ambiguous P:\projects\common\boost_1.36.0/boost/function/function_base.hpp:99: error: candidates are: template<class Signature> struct boost::function s:\programming\mingw\bin\../lib/gcc/mingw32/4.3.2/include/c++/tr1_impl/functional:1464: error: template<class _Signature> struct std::function boost_test1.cpp:30: error: functional cast expression list treated as compound expression boost_test1.cpp:30: error: expected primary-expression before 'unsigned' boost_test1.cpp:30: error: expected `;' before 'unsigned' boost_test1.cpp:31: error: reference to 'function' is ambiguous P:\projects\common\boost_1.36.0/boost/function/function_base.hpp:99: error: candidates are: template<class Signature> struct boost::function s:\programming\mingw\bin\../lib/gcc/mingw32/4.3.2/include/c++/tr1_impl/functional:1464: error: template<class _Signature> struct std::function boost_test1.cpp:31: error: expected primary-expression before 'unsigned' boost_test1.cpp:31: error: expected `;' before 'unsigned' boost_test1.cpp:32: error: reference to 'function' is ambiguous P:\projects\common\boost_1.36.0/boost/function/function_base.hpp:99: error: candidates are: template<class Signature> struct boost::function s:\programming\mingw\bin\../lib/gcc/mingw32/4.3.2/include/c++/tr1_impl/functional:1464: error: template<class _Signature> struct std::function boost_test1.cpp:32: error: 'f3' was not declared in this scope boost_test1.cpp:32: error: 'f2' was not declared in this scope As you can see <tr1/functional> header isn't explicitly included but compilation was failed. I mean that code which is conform to the some boost examples or other *same* guidelines which explicitly or implicitly expose both 'boost' and 'std' namespaces into global or local scope could become automatically uncompilable... -- Best Regards, Sergey mailto:flex_ferrum@artberg.ru

on Wed Nov 12 2008, Sergey Sadovnikov <flex_ferrum-AT-artberg.ru> wrote:
Absolutely right, but... Let's see an example. Just get the one of the boost test cases (http://www.boost.org/doc/libs/1_37_0/libs/function/test/lambda_test.cpp)and try to compile with gcc 4.3.2:
I would never claim that all the Boost test cases follow a good practice.
----------------------------------------------------------------------- // Boost.Function library
// Copyright Douglas Gregor 2002-2003. Use, modification and // distribution is subject to the Boost Software License, Version // 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt)
// For more information, see http://www.boost.org
#include <iostream> #include <cstdlib>
#include <boost/test/minimal.hpp> #include <boost/lambda/lambda.hpp> #include <boost/lambda/bind.hpp> #include <boost/function.hpp>
using namespace std; using namespace boost; using namespace boost::lambda;
static unsigned func_impl(int arg1, bool arg2, double arg3) { return abs (static_cast<int>((arg2 ? arg1 : 2 * arg1) * arg3)); }
int test_main(int, char*[]) { function <unsigned(bool, double)> f1 = bind(func_impl, 15, _1, _2); function <unsigned(double)> f2 = bind(f1, false, _1); function <unsigned()> f3 = bind(f2, 4.0);
f3();
return 0; }
This would also fail if you include <boost/bind.hpp>
Compiler says: P:\projects\Tests\Sandbox\C++0x\gcc43>g++ -std=c++0x -IP:\projects\common\boost_1.36.0 boost_test1.cpp boost_test1.cpp: In function 'int test_main(int, char**)': boost_test1.cpp:30: error: reference to 'function' is ambiguous
<snip>
As you can see <tr1/functional> header isn't explicitly included but compilation was failed.
Yes.
I mean that code which is conform to the some boost examples or other *same* guidelines which explicitly or implicitly expose both 'boost' and 'std' namespaces into global or local scope could become automatically uncompilable...
Yes, really, I understood the problem the first time you described it. It's very bad, for people with code like that. I argued once with Herb that using directives are a bad idea in general, and he said, "if your code breaks, you just add qualification and fix it." So I can't account for any programming guidelines he's given that sanction using directives. In the few cases where it's okay, you have tight control over the future evolution of each namespace involved, so you know that collisions won't happen. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

Hello, David. Wednesday, November 12, 2008 at 11:00:24 PM you wrote:
Absolutely right, but... Let's see an example. Just get the one of the boost test cases (http://www.boost.org/doc/libs/1_37_0/libs/function/test/lambda_test.cpp)and try to compile with gcc 4.3.2:
DA> I would never claim that all the Boost test cases follow a good DA> practice. :) But the same code is present in the documentation. For example, boost::assign (http://www.boost.org/doc/libs/1_37_0/libs/assign/doc/index.html), or boost::spirit (http://www.boost.org/doc/libs/1_37_0/libs/spirit/classic/example/fundamental...), or boost::asio (http://www.boost.org/doc/libs/1_37_0/doc/html/boost_asio/example/porthopper/...). Developers follow this documentation and produce potentially uncompilable code... Some kind of delayed-action mine. I agree what developer has to use his own head. BTW such developer suppose what boosters knows what they do and their code is a high-quality code. Developer is wrong? :)
I mean that code which is conform to the some boost examples or other *same* guidelines which explicitly or implicitly expose both 'boost' and 'std' namespaces into global or local scope could become automatically uncompilable...
DA> Yes, really, I understood the problem the first time you described it. DA> It's very bad, for people with code like that. I argued once with Herb DA> that using directives are a bad idea in general, and he said, "if your DA> code breaks, you just add qualification and fix it." So I can't account DA> for any programming guidelines he's given that sanction using DA> directives. In the few cases where it's okay, you have tight control DA> over the future evolution of each namespace involved, so you know that DA> collisions won't happen. In other words you are offering to developers to make a choose between simpler code and unambiguous code. It is clear what second choice is preferable. But both boost and STL main goal is to make code and coding process simpler. Isn't it? And what we will have? At least: 1. Ambiguous names in the 'polluted' global scope. Ok, it is a bad practice and let's forget about it. 2. Compatible (or non-compatible?) boost-conformant and C++0x-conformant code. Could developer simply cast boost::shared_ptr to std::shared_ptr and back? Could developers use std::bind everywhere where boost::bind is suitable? What about tuples, functions, etc.? 3. Quite complex form of std binders. Because we all agreed what std and boost namespaces will not exposed into global scope, developer have to write (for example): std::for_each(v.begin(), v.end(), std::bind(&foo, std::placeholders::_1); If developer will want to simplify his life and will write somewhere: using namespace std::placeholders; ... He will take a dial with boost::bind placeholders which are already in the global scope... And he couldn't avoid this ambiguous because of some other boost headers include boost/bind.hpp directly (thread, statechart, python, multi_index, algorithm and other). 4. Some amount of boost code relay on the boost implementation of the new TR1 facilities. Is this code will work with corresponding C++0x-conformant facilities? Let's try: ----------------------------------------------------------------------- #include <iostream> #include <map> #include <algorithm> #include <iterator> #include <tr1/functional> #include <boost/iterator/transform_iterator.hpp> int main(int, char*[]) { std::map<int, int> test_map; test_map[0] = 10; test_map[1] = 5; test_map[5] = 8; test_map[3] = 20; typedef std::map<int,int>::value_type vt; std::copy(boost::make_transform_iterator(test_map.begin(), std::tr1::bind(&vt::second, std::tr1::placeholders::_1)), boost::make_transform_iterator(test_map.end(), std::tr1::bind(&vt::second, std::tr1::placeholders::_1)), std::ostream_iterator<int>(std::cout, "\n")); } ----------------------------------------------------------------------- This code can't be compiled both with g++ 4.3.2 and VS2008 SP1. Both compilers "complain" on the "result_type" absence in the binder passed to the transform iterator. I suppose what this is the issue in the vendor's TR1 implementation but I (as a C++ developer) have to avoid such cases and have to make my code more complex. But what about another code? Today it isn't so scary because of TR1 implementations are mostly experimental and almost all libraries relay on the boost facilities. But what we will have in the future when some libraries will relay on the boost, other relay on the STL and developer will have to use both ones for some reason? In one piece of code they have to write something like "std::bind(..., std::placeholders::_1)", in other piece "boost::bind(..., ::_1)", somewhere "boost::shared_ptr", somewhere else "std::shared_ptr"... A so on and on and on and on... And always keep in mind which version of class they have to use in certain place... And nothing about compatibility of this classes... Or am I wrong, and just dramatizing the situation, and "We emphasize libraries that *work well with the C++ Standard Library*. Boost libraries are intended to be widely useful, and usable across a broad spectrum of applications." slogan still true? TR1 will become the part of the C++ Standard Library in the next year, I suppose. :) -- Best Regards, Sergey mailto:flex_ferrum@artberg.ru

on Wed Nov 12 2008, Sergey Sadovnikov <flex_ferrum-AT-artberg.ru> wrote:
This code can't be compiled both with g++ 4.3.2 and VS2008 SP1. Both compilers "complain" on the "result_type" absence in the binder passed to the transform iterator. I suppose what this is the issue in the vendor's TR1 implementation
No, it's simpler than that. transform_iterator requires AdaptableUnaryFunction and the result of tr1::bind is not one of those. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

Hello, David. Thursday, November 13, 2008 at 5:33:36 AM you wrote: DA> No, it's simpler than that. transform_iterator requires DA> AdaptableUnaryFunction and the result of tr1::bind is not one of those. But result of boost::bind *is* one of those? -- Best Regards, Sergey mailto:flex_ferrum@artberg.ru

on Thu Nov 13 2008, Sergey Sadovnikov <flex_ferrum-AT-artberg.ru> wrote:
Hello, David.
Thursday, November 13, 2008 at 5:33:36 AM you wrote:
DA> No, it's simpler than that. transform_iterator requires DA> AdaptableUnaryFunction and the result of tr1::bind is not one of those. But result of boost::bind *is* one of those?
Seems likely. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

Hello, Michael. Tuesday, November 11, 2008 at 11:09:03 PM you wrote: MM> Correct, TR1 shared_ptr doesn't support boost::make_shared for instance. Please, look at the C++0x last working draft, section 20.8.13.2.6. -- Best Regards, Sergey mailto:flex_ferrum@artberg.ru

Sergey Sadovnikov wrote:
Many of the boost libraries have evolved beyond their TR1 counter parts. Boost's shared_ptr is a good example of this. I primarily use VC9 SP1 which has a tr1 implementation but I use features of boost::shared_ptr that std::tr1::shared_ptr doesn't have.
Do you mean what there is no way to make boost and TR1 implementations don't conflict each other?
IMO they don't conflict *now*, not unless carelessly polute the global namespace. BTW Boost.TR1 has the semantics you were looking for: #include <memory> // with boost/tr1/tr1 in the include path std::tr1::shared_ptr<foo> fooptr; // uses vendor supplied shared_ptr if available, otherwise Boost version.
And, for example, boost::shared_ptr couldn't be transparently replaced by corresponding TR1 class?
The Boost versions of the TR1 components typically have extensions that aren't available in the standard versions. Further some people may prefer to use *the same implementation*, ie the Boost one, across multiple platforms and compilers. IMO the Boost versions should continue to exist and evolve. John.

Hello, John. Wednesday, November 12, 2008 at 12:41:11 PM you wrote: JM> Sergey Sadovnikov wrote:
Do you mean what there is no way to make boost and TR1 implementations don't conflict each other?
JM> IMO they don't conflict *now*, not unless carelessly polute the global JM> namespace. But, as I already said, some boost examples and boost test cases, and boost documentation pages contains global and local using-declarations. So such 'pollution' conform to the: 1. Boost documentation 2. Boost examples 3. Boost tests 4. Expert opinions (such as Herb Sutter - see "More Exceptional C++", item 40, Namespace Rule #3). JM> BTW Boost.TR1 has the semantics you were looking for: JM> #include <memory> // with boost/tr1/tr1 in the include path JM> std::tr1::shared_ptr<foo> fooptr; // uses vendor supplied shared_ptr if JM> available, otherwise Boost version. Of course. I wonder if all boost headers refer only to the boost/tr1/tr1. But even if you in your projects refer to the boost/tr1/tr1/memory, some boost headers (for example, date_time libraryt) refer directly to the boost/shared_ptr. And you automatically have two different implementation in the two different namespaces.
And, for example, boost::shared_ptr couldn't be transparently replaced by corresponding TR1 class?
JM> The Boost versions of the TR1 components typically have extensions that JM> aren't available in the standard versions. Further some people may prefer JM> to use *the same implementation*, ie the Boost one, across multiple JM> platforms and compilers. IMO the Boost versions should continue to exist JM> and evolve. But another people would prefer std-conformant implementation of this facilities. :) Imagine what you want to use some third-party library which only C++0x-conformant, with you code which use same boost classes. In this case you will have a choice: 1. Use code like this: std::bind(&foo, std::palceholders::_1, std::palceholders::_2 /* etc. */) boost::shared_ptr<SomeType> sp(new SomeType, boost::bind(&SomeType::Release, ::_1); 2. Take a deal with ambiguous name resolution... What you choose? I agree what it would be great if this two implementations will co-exists. But it also will great if this implementations will not conflict each other within global scope. -- Best Regards, Sergey mailto:flex_ferrum@artberg.ru

on Tue Nov 11 2008, Sergey Sadovnikov <flex_ferrum-AT-artberg.ru> wrote:
Hello All,
Today there is at least two implementations of TR1 library extensions shipped with compilers. I mean VS 2008 SP1 and gcc 4.3.x STL. Because of boost has it's own implementation of TR1 there is some problems with migrating code to this compilers. For example:
1. There is many ambiguous names if both boost and std::tr1 exposed into global namespace.
"Doctor, it hurts when I do this..." ;-)
2. boost::transform_iterator knows nothing about std::tr1::bind shipped with VS2008 compiler.
What is it supposed to "know?" -- Dave Abrahams BoostPro Computing http://www.boostpro.com

Hello, David. Wednesday, November 12, 2008 at 8:11:36 PM you wrote:
2. boost::transform_iterator knows nothing about std::tr1::bind shipped with VS2008 compiler.
DA> What is it supposed to "know?" Once more about binders to the data member. Last standard working draft (Doc No: N2798=08-0308, Date: 2008-10-04), [func.require] section: -------------------------------- 3. If a call wrapper (20.7.1) has a weak result type the type of its member type result_type is based on the type T of the wrapper’s target object (20.7.1): — if T is a function, reference to function, or pointer to function type, result_type shall be a synonym for the return type of T; — if T is a pointer to member function, result_type shall be a synonym for the return type of T; — if T is a class type with a member type result_type, then result_type shall be a synonym for T::result_type; — otherwise result_type shall not be defined. -------------------------------- Is this mean what class datamember "call wrappers" hasn't to define 'result_type' member? And there is no way to determine result type of the following expression: std::tr1::bind(&std::pair<int, int>::second, std::tr1::placeholders::_1)); ? -- Best Regards, Sergey mailto:flex_ferrum@artberg.ru
participants (6)
-
David Abrahams
-
Deng Xiyue
-
John Maddock
-
Michael Marcin
-
Sebastian Redl
-
Sergey Sadovnikov