Я только что натолкнулся на любопытную ошибку std :: эксперимент :: пропагата_конст.Следующий фрагмент демонстрирует проблему
#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, потому что иногда ваши форвардные объявления будут его ломать.
Буду признателен, если кто-тообъясните мне, почему компиляция не удалась в текущей реализации пропагата_конст .Это как-то связано с
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.
PS Интересно, знают ли разработчики компилятора об этом?или нет.