#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和类似的特征给出无法访问的构造函数的正确答案.