propagate_const 和前向声明
propagate_const and forward declaration
我刚刚 运行 遇到了一个奇怪的 std::experimental::propagate_const 错误。
以下片段演示了问题
#include <memory>
#include <experimental/propagate_const>
#include <map>
class FWD;
//compiles
class A
{
std::unique_ptr<FWD> m;
};
//compiles
class B
{
std::experimental::propagate_const<std::unique_ptr<FWD>> m;
};
//compiles
class C
{
std::unique_ptr<std::map<int, FWD>> m;
};
//does not compile!
class D
{
std::experimental::propagate_const<std::unique_ptr<std::map<int, FWD>>> m;
};
所以你不能只用传播 unique_ptr 替换 unique_ptr 因为有时你的前向声明会破坏它。
如果有人能向我解释为什么在 propagate_const 的当前实现中编译失败,我将不胜感激。
跟
有关系
typedef remove_reference_t<decltype(*std::declval<_Tp&>())> element_type;
因为解决方法是:
template <typename T, typename = void>
struct get_element_type
{
using type = std::remove_reference_t<decltype(*std::declval<T&>())>;
};
template <typename T>
struct get_element_type<T, typename std::enable_if<!std::is_void<typename T::element_type>::value>::type>
{
using type = typename T::element_type;
};
// Namespaces and class declaration...
using element_type = typename get_element_type<T>::type;
经过测试的编译器:clang、gcc。
P.S。我想知道编译器开发者是否知道它。
通常禁止实例化具有不完整类型的标准库模板。
std::map
也不例外。
使用 _Tp = std::unique_ptr<std::map<int, FWD>>
查询 decltype(*std::declval<_Tp&>())
需要实例化 _Tp
的所有关联 类 以查找潜在的朋友 operator*
声明.
在关联的 类 中有 std::map<int, FWD>
。
std::map<int, FWD>
的实例化调用未定义的行为。
我已经向 propagate_const 提交了一个补丁,它取代了现有的解决方案并解决了与上述解决方案类似的问题,但不依赖于 SFINAE:
template<class U>
struct detect_element_type {
using type = typename U::element_type;
};
template<class U>
struct detect_element_type<U*> {
using type = U;
};
using element_type = typename detect_element_type<T>::type;
我刚刚 运行 遇到了一个奇怪的 std::experimental::propagate_const 错误。 以下片段演示了问题
#include <memory>
#include <experimental/propagate_const>
#include <map>
class FWD;
//compiles
class A
{
std::unique_ptr<FWD> m;
};
//compiles
class B
{
std::experimental::propagate_const<std::unique_ptr<FWD>> m;
};
//compiles
class C
{
std::unique_ptr<std::map<int, FWD>> m;
};
//does not compile!
class D
{
std::experimental::propagate_const<std::unique_ptr<std::map<int, FWD>>> m;
};
所以你不能只用传播 unique_ptr 替换 unique_ptr 因为有时你的前向声明会破坏它。
如果有人能向我解释为什么在 propagate_const 的当前实现中编译失败,我将不胜感激。 跟
有关系typedef remove_reference_t<decltype(*std::declval<_Tp&>())> element_type;
因为解决方法是:
template <typename T, typename = void>
struct get_element_type
{
using type = std::remove_reference_t<decltype(*std::declval<T&>())>;
};
template <typename T>
struct get_element_type<T, typename std::enable_if<!std::is_void<typename T::element_type>::value>::type>
{
using type = typename T::element_type;
};
// Namespaces and class declaration...
using element_type = typename get_element_type<T>::type;
经过测试的编译器:clang、gcc。
P.S。我想知道编译器开发者是否知道它。
通常禁止实例化具有不完整类型的标准库模板。
std::map
也不例外。使用
_Tp = std::unique_ptr<std::map<int, FWD>>
查询decltype(*std::declval<_Tp&>())
需要实例化_Tp
的所有关联 类 以查找潜在的朋友operator*
声明.在关联的 类 中有
std::map<int, FWD>
。std::map<int, FWD>
的实例化调用未定义的行为。
我已经向 propagate_const 提交了一个补丁,它取代了现有的解决方案并解决了与上述解决方案类似的问题,但不依赖于 SFINAE:
template<class U>
struct detect_element_type {
using type = typename U::element_type;
};
template<class U>
struct detect_element_type<U*> {
using type = U;
};
using element_type = typename detect_element_type<T>::type;