c – std :: unordered_map :: emplace问题与私有/删除的复制构造函数

前端之家收集整理的这篇文章主要介绍了c – std :: unordered_map :: emplace问题与私有/删除的复制构造函数前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
以下代码使用 gcc 4.7.2(mingw)进行编译
#include <unordered_map>
#include <tuple>

struct test
{
        test() =default;
    private:
        test(test const&) =delete;
};

int main()
{
    std::unordered_map<char,test> map;

    map.emplace(
        std::piecewise_construct,std::forward_as_tuple('a'),std::forward_as_tuple()
    );
}

如果我从test(test const&)= delete更改test中的copy构造函数;测试(test const&)= default;然而,模板错误呕吐似乎抱怨const test&不可转换为测试(文本here).不应该工作吗?或者如果不是,他们不应该给出错误

解决方法

如果你看模板错误呕吐更仔细,你会看到这块胡萝卜:
test.exe.cpp:8:3: error: 'constexpr test::test(const test&)' is private

这是问题的线索.

GCC 4.7.2不进行访问检查,作为模板参数推导的一部分(如C 03所要求的).is_convertible trait是使用SFINAE实现的,它依赖于模板参数的推导,如果重载分辨率选择了一个私有构造函数,则扣除成功,但是访问检查失败,因为所选的构造函数是私有的.这是GCC 4.7的一个问题,因为在14.8.2 [temp.deduct]中没有改变遵循新的C11规则,它说:

-8- If a substitution results in an invalid type or expression,type deduction fails. An invalid type or expression is one that would be ill-formed if written using the substituted arguments. [ Note: Access checking is done as part of the substitution process. —end note ]

这是对以前的扣除规则的巨大变化,以前的段落说

-8- If a substitution results in an invalid type or expression,type deduction fails. An invalid type or expression is one that would be ill-formed if written using the substituted arguments. Access checking is not done as part of the substitution process. Consequently,when deduction succeeds,an access error could still result when the function is instantiated.

在07年的C 0x进程中,这个变化已经相当晚了,而且在C11中让SFINAE完全可以

GCC 4.8实现新的规则,所以is_convertible和类似的特征给出无法访问的构造函数的正确答案.

猜你在找的C&C++相关文章