繁体   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

我需要使用一些使用std::tr1::shared_ptr旧遗留代码。 我需要包含的标题包含#include <tr1/memory>#include <tr1/functional> 在我的代码中,我想使用std::functionstd::bind ,因为我们的编译器支持这些。

这适用于gcc 4.6.3和4.7.3。 在4.9.2,5.1.x和5.2.0中,这会导致编译器错误。 它似乎是由于<tr1/functional> -include而发生的。

我写了一个重现这个问题的小例子:

#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,没有#include <tr1/functional> ,编译好。 在我的本地机器上测试过。

gcc-4.6.3, #include <tr1/functional> ,编译正常。 在我的本地机器上测试过。

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

gcc-5.1, #include <tr1/functional> ,编译错误: http//ideone.com/sRWQLn

我根本没有使用任何std::tr1::functionstd::tr1::bind ,我从遗留代码中唯一使用的是std::tr1::shared_ptr对象。

为什么#include <tr1/functional>会影响非tr1 std::function / std::bind 或者这里发生了什么?

编辑:根据GNU C ++ Library Manual,第3章 :“ 第二条规则的一个特例是TR1和C ++ 11设施的混合。有可能(虽然不是特别谨慎)包括TR1版本和C ++ 11版本的标题在同一翻译单元中

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

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

并在SFINAE中使用它。 表达式SFINAE意味着如果调用表达式不编译,则转换构造函数将从重载集中删除。

问题在于__callable_functor 它的工作是将指针指向成员,以便它们可以与普通的函数调用语法一起使用。 它是一个保留的名称,所以没有其他人应该使用它...好吧,除了标准库的其他组件。 我们在<functional>std::__callable_functor ,在<tr1/functional> std::tr1::__callable_functor 并且因为std::tr1是一个关联的命名空间(由于在Foo::test的签名中使用了std::tr1::shared_ptr<int> ),你最终会产生歧义。

编辑 :报告为错误68995

暂无
暂无

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

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