use*_*267 10 c++ gcc unordered-map mingw c++11
使用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()
);
}
Run Code Online (Sandbox Code Playgroud)
如果我改变了拷贝构造函数test从test(test const&) =delete;到test(test const&) =default;然而,模板错误呕吐,似乎抱怨const test&不被转换为test(文字在这里).不应该工作吗?或者如果没有,他们是否应该给出错误?
Jon*_*ely 11
如果你仔细看看模板错误呕吐,你会看到这块胡萝卜:
test.exe.cpp:8:3: error: 'constexpr test::test(const test&)' is private
Run Code Online (Sandbox Code Playgroud)
这是问题的线索.
GCC 4.7.2不作为模板参数推导的一部分进行访问检查(如C++ 03所要求的那样).is_convertible特性是使用SFINAE实现的,它依赖于模板参数推导,并且如果重载决策选择了私有构造函数参数推导成功,但随后访问检查失败,因为所选的构造函数是私有的.这是GCC 4.7的问题,因为它没有被更改为遵循14.8.2 [temp.deduct]中的新C++ 11规则,该规则说:
-8-如果替换导致无效的类型或表达式,则类型推导失败.如果使用替换参数写入,则无效的类型或表达式将是格式错误的.[注意:访问检查是作为替换过程的一部分完成的. - 尾注]
这是对先前扣除规则的巨大改变,此前段落说
-8-如果替换导致无效的类型或表达式,则类型推导失败.如果使用替换参数写入,则无效的类型或表达式将是格式错误的.访问检查不是替换过程的一部分.因此,当推导成功时,在实例化函数时仍可能导致访问错误.
DR 1170在C++ 0x过程中进行了很晚的改变,并使得SFINAE在C++ 11中非常出色:)
GCC 4.8实现了新规则,因此is_convertible类似的特性为不可访问的构造函数提供了正确的答案.
| 归档时间: |
|
| 查看次数: |
1871 次 |
| 最近记录: |