I a trying to make a std::variant that can contain a vector of the same variant:
class ScriptParameter;
using ScriptParameter = std::variant<bool, int, double, std::string, std::vector<ScriptParameter> >;
I am getting ScriptParameter redefinition. It think it is possibly because a template parameter cannot be forward declared?
Is there a way to achieve a variant that could also contain an array of same typed variants?
The class template std::variant represents a type-safe union. An instance of std::variant at any given time either holds a value of one of its alternative types, or in the case of error - no value (this state is hard to achieve, see valueless_by_exception).
Boost. Variant, part of collection of the Boost C++ Libraries. It is a safe, generic, stack-based discriminated union container, offering a simple solution for manipulating an object from a heterogeneous set of types in a uniform manner.
Since this function is specific to a given type, you don't need RTTI to perform the operations required by std::any .
According to cppreference ::std::variant must not allocate dynamic memory. As with unions, if a variant holds a value of some object type T, the object representation of T is allocated directly within the object representation of the variant itself. Variant is not allowed to allocate additional (dynamic) memory.
Since the forward declaration says ScriptParameter
is a class, you can't use using
alias. However, nothing is inherently wrong here, since vector
is only a pointer, there is no real circular dependency.
You can use inheritance:
class ScriptParameter;
class ScriptParameter
: public std::variant<bool, int, double, std::string, std::vector<ScriptParameter> >
{
public:
using base = std::variant<bool, int, double, std::string, std::vector<ScriptParameter> >;
using base::base;
using base::operator=;
};
int main() {
ScriptParameter sp{"hello"};
sp = 1.0;
std::vector<ScriptParameter> vec;
sp = vec;
std::cout << sp.index() << "\n";
}
Use the type level fixed-point operator.
#include <vector>
#include <variant>
#include <string>
// non-recursive definition
template<class T>
using Var = std::variant<int, bool, double, std::string, std::vector<T>>;
// tie the knot
template <template<class> class K>
struct Fix : K<Fix<K>>
{
using K<Fix>::K;
};
using ScriptParameter = Fix<Var>;
// usage example
int main()
{
using V = std::vector<ScriptParameter>;
ScriptParameter k {V{1, false, "abc", V{2, V{"x", "y"}, 3.0}}};
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With