У меня есть класс, который выглядит примерно так:
template<class KeyType, class... Types>
class BasicCompound
{
public:
using mapped_type = std::variant
<
ValueWrapper<BasicCompound>
, ValueWrapper<Types>...
>;
using key_type = KeyType;
// Accessors for retreiving and modifying content
// ...
private:
std::map<key_type, mapped_type> m_content;
};
ValueWrapper
решает поместить содержимое либо в строку, либо в std::unique_ptr
.Было бы возможно с подобным интерфейсом, возможно через некоторый прокси, сделать рекурсивность необязательной?Под необязательным я подразумеваю, что пользователь не должен автоматически получать возможность хранить BasicCompound
внутри себя, а скорее указывать его в списке типов.
Что я подумал:
- A
using
не работает.Сам по себе новый тип не может быть определен, и предопределение следующего определения типа не допускается. - Добавление
bool
в список типов и использование std::conditional_t
для mapped_type
.Однако, если пользователь хочет сохранить X<BasicCompound>
, этот подход не выполняется. - Внедрить
mapped_type
извне.Тогда я не могу скрыть использование вещи ValueWrapper
. Использование наследования над typdef
подобно
struct MyCompound : BasicCompound<std::string, MyCompound, int> {};
Это работает, но тогда структура не является строго рекурсивной,поскольку MyCompound
теперь отличается от BasicCompound
.Возможно, CRTP-подобный подход мог бы решить эту проблему, но тогда внутренний составной тип должен обрабатываться иначе, чем другие типы.