In C++, how to make a variant that can contain a vector of of same variant?
bitwise operator in c
logical operators in c
sign in c
ternary operator in c
conditional operator in c
assignment operators in c
relational operators in c
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?
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"; }
C - Operators, This is a list of operators in the C and C++ programming languages. All the operators listed exist in C++; the fourth column "Included in C", states whether an We would like to show you a description here but the site won’t allow us.
I'm not sure a recursive definition makes sense in this case. It allows arbitrarily many nested vectors inside a single ScriptParameter
. (Essentially we're saying that a script parameter is either a single value or an entire forest of values.) Splitting the definition in two might work better:
// Represents the value of a single parameter passed to a script using ScriptParameter = std::variant<bool, int, double, std::string>; // Represents a collection of one or many script parameters using ScriptParameterSet = std::variant<ScriptParameter, std::vector<ScriptParameter>>;
Alternatively, if the goal here is to define a parameter as one of a set of choices plus a vector of those same choices, you could try a little template magic:
template <class T, class U> struct variant_concat; template <class... T, class U> struct variant_concat<std::variant<T...>, U> { using type = std::variant<T..., U>; }; template <class T, class U> using variant_concat_t = typename variant_concat<T, U>::type; using PrimitiveScriptParameter = std::variant<bool, int, double, std::string>; using ScriptParameter = variant_concat_t< PrimitiveScriptParameter, std::vector<PrimitiveScriptParameter>>;
This should address Lightness's usability concern below.
Operators in C and C++, The result of the operation of a logical operator is a boolean value either true or false. For example, the logical AND represented as '&&' operator in C or C++ C definition, the third letter of the English alphabet, a consonant. See more.
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}}}; }
Operators in C / C++, Thus the functionality of C language is incomplete without the use of operators. Operators allow us to perform different kinds of operations on operands. In C Cprogramming.com covers both C and C++ in-depth, with both beginner-friendly tutorials, more advanced articles, and the book Jumping into C++, which is a highly reviewed, friendly introduction to C++.
Operators in C, C language supports a rich set of built-in operators. An operator is a symbol that tells the compiler to perform certain mathematical or logical manipulations. &c. ( dated ) Alternative form of etc. : … and so on , …and other things . 1612 , George Wither, Epithalamia, Or Nuptiall Poems Upon the Most Blessed and Happie Mariage Betweene the High and Mightie Prince Frederick the Fifth, Count Palatine of the Rhein, &c. , and Princesse Elizabeth, Sole Daughter to Iames, by the Grace of God, King of
C Operators, It's equivalent to: rot = rot * 5;. It's part of a family of operators called 'compound assignment' operators. You can see the full list of them here: C--(pronounced cee minus minus) is a C-like programming language.Its creators, functional programming researchers Simon Peyton Jones and Norman Ramsey, designed it to be generated mainly by compilers for very high-level languages rather than written by human programmers.
What exactly does "*=" mean in C programming?, What is “&” and “*” operators in C?- “*” Operator is used as pointer to a variable. Example: * a where * is pointer to the variable a. Define &c. &c synonyms, &c pronunciation, &c translation, English dictionary definition of &c. Abbr. etc. And other unspecified things of the same class; and so forth. or 1. and the rest; and others; and so forth: used at the end of a list to indicate
Comments
- This rather sounds like a more generic flaw in your design. What do you really want to achieve?
- I don't think C++ supports the chicken-and-egg pattern.
- Looks like a naming conflict? What are you expecting the compiler to understand
ScriptParameter
as? The type, or the forward declared class? - related/dupe: stackoverflow.com/questions/39454347/…
- The array specifically shouldn't be possible. What would the size of something like that be?
- Exactly what I did four weeks ago. Sadly making a
std::map
/std::set
of the same is not possible. - This doesn't really answer the question and I'm not sure we can say that the OP's approach doesn't fit their use case. I am currently working with code that does what they're doing and it makes sense. Your solution simplifies the type definitions a bit but will complicate usage/visitors quite a lot.
- It is hard to tell since the OP declined to supply context. Nevertheless, the recursive definition of a parameter does seem a little off to me, so I thought I'd offer this.
- Yep nice one. ^_^