I need to use some old legacy code which uses std::tr1::shared_ptr. The header that I need to include has both #include <tr1/memory> and #include <tr1/functional>. In my code I want to use std::function and std::bind, since our compiler supports these.
This works fine with gcc 4.6.3 and 4.7.3. In 4.9.2, 5.1.x and 5.2.0 this results in a compiler error. It seems to happen due to the <tr1/functional>-include.
I wrote a small example that reproduce this problem:
#include <tr1/memory>
#include <functional>
#include <tr1/functional>
struct Foo {
void test(std::tr1::shared_ptr<int> i) {}
};
int main() {
Foo f;
std::function<void(std::tr1::shared_ptr<int>)> func = std::bind(&Foo::test, f, std::placeholders::_1);
return 0;
}
gcc-4.6.3, without #include <tr1/functional>, compiles OK. Tested on my local machine.
gcc-4.6.3, with #include <tr1/functional>, compiles OK. Tested on my local machine.
gcc-5.1, without #include <tr1/functional>, compiles OK: http://ideone.com/XrkAXT
gcc-5.1, with #include <tr1/functional>, compiler error: http://ideone.com/sRWQLn
I'm not using any std::tr1::function or std::tr1::bind at all, and the only thing I use from the legacy code is a std::tr1::shared_ptr object.
Why does the #include <tr1/functional> affect the non-tr1 std::function / std::bind? Or what's happening here?
Edit: According to GNU C++ Library Manual, Chapter 3: "A special case of the second rule is the mixing of TR1 and C++11 facilities. It is possible (although not especially prudent) to include both the TR1 version and the C++11 version of header in the same translation unit"
There was a change in the standard that requires the implementation to constrain
std::function's constructor so that it's not convertible from everything under the sun, but only from actual callables, so libstdc++ computes the return type with:and uses it in the SFINAE. Expression SFINAE means that if the call expression doesn't compile, the converting constructor is removed from the overload set.
The problem is with that
__callable_functor. Its job is to wrap pointer-to-members so that they can be used with the normal function call syntax. And it's a reserved name so nobody else should be using it...well, except other components of the standard library. We havestd::__callable_functorin<functional>andstd::tr1::__callable_functorin<tr1/functional>. And becausestd::tr1is an associated namespace (thanks to the use ofstd::tr1::shared_ptr<int>in the signature ofFoo::test), you end up with an ambiguity.Edit: reported as bug 68995.