简体   繁体   English

将std :: tr1 :: shared_ptr与std :: function / std :: bind混合会导致编译器错误与更新的gcc

[英]Mixing std::tr1::shared_ptr with std::function / std::bind causes compiler errors with newer gcc

I need to use some old legacy code which uses std::tr1::shared_ptr . 我需要使用一些使用std::tr1::shared_ptr旧遗留代码。 The header that I need to include has both #include <tr1/memory> and #include <tr1/functional> . 我需要包含的标题包含#include <tr1/memory>#include <tr1/functional> In my code I want to use std::function and std::bind , since our compiler supports these. 在我的代码中,我想使用std::functionstd::bind ,因为我们的编译器支持这些。

This works fine with gcc 4.6.3 and 4.7.3. 这适用于gcc 4.6.3和4.7.3。 In 4.9.2, 5.1.x and 5.2.0 this results in a compiler error. 在4.9.2,5.1.x和5.2.0中,这会导致编译器错误。 It seems to happen due to the <tr1/functional> -include. 它似乎是由于<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. gcc-4.6.3,没有#include <tr1/functional> ,编译好。 Tested on my local machine. 在我的本地机器上测试过。

gcc-4.6.3, with #include <tr1/functional> , compiles OK. gcc-4.6.3, #include <tr1/functional> ,编译正常。 Tested on my local machine. 在我的本地机器上测试过。

gcc-5.1, without #include <tr1/functional> , compiles OK: http://ideone.com/XrkAXT gcc-5.1,没有#include <tr1/functional> ,编译好了: http//ideone.com/XrkAXT

gcc-5.1, with #include <tr1/functional> , compiler error: http://ideone.com/sRWQLn gcc-5.1, #include <tr1/functional> ,编译错误: 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. 我根本没有使用任何std::tr1::functionstd::tr1::bind ,我从遗留代码中唯一使用的是std::tr1::shared_ptr对象。

Why does the #include <tr1/functional> affect the non-tr1 std::function / std::bind ? 为什么#include <tr1/functional>会影响非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 " 编辑:根据GNU C ++ Library Manual,第3章 :“ 第二条规则的一个特例是TR1和C ++ 11设施的混合。有可能(虽然不是特别谨慎)包括TR1版本和C ++ 11版本的标题在同一翻译单元中

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: 标准中有一个变化需要实现来约束std::function的构造函数,以便它不能从sun下的所有东西转换,而只能从实际的callables转换,所以libstdc ++计算返回类型:

template<typename _Functor>
using _Invoke = decltype(__callable_functor(std::declval<_Functor&>())
                         (std::declval<_ArgTypes>()...) );

and uses it in the SFINAE. 并在SFINAE中使用它。 Expression SFINAE means that if the call expression doesn't compile, the converting constructor is removed from the overload set. 表达式SFINAE意味着如果调用表达式不编译,则转换构造函数将从重载集中删除。

The problem is with that __callable_functor . 问题在于__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 have std::__callable_functor in <functional> and std::tr1::__callable_functor in <tr1/functional> . 我们在<functional>std::__callable_functor ,在<tr1/functional> std::tr1::__callable_functor And because std::tr1 is an associated namespace (thanks to the use of std::tr1::shared_ptr<int> in the signature of Foo::test ), you end up with an ambiguity. 并且因为std::tr1是一个关联的命名空间(由于在Foo::test的签名中使用了std::tr1::shared_ptr<int> ),你最终会产生歧义。

Edit : reported as bug 68995 . 编辑 :报告为错误68995

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM