我正在尝试创建一个能够包含相同变量类型的向量的std::variant:
class ScriptParameter;
using ScriptParameter = std::variant<bool, int, double, std::string, std::vector<ScriptParameter> >;
我遇到了ScriptParameter重新定义的问题。我认为这可能是由于无法提前声明模板参数导致的?
有没有办法实现一个变量,它还可以包含相同类型变量的数组?
我正在尝试创建一个能够包含相同变量类型的向量的std::variant:
class ScriptParameter;
using ScriptParameter = std::variant<bool, int, double, std::string, std::vector<ScriptParameter> >;
我遇到了ScriptParameter重新定义的问题。我认为这可能是由于无法提前声明模板参数导致的?
有没有办法实现一个变量,它还可以包含相同类型变量的数组?
由于前向声明表示ScriptParameter
是一个类,因此您不能使用using
别名。 但是,在这里本质上没有什么错误,因为vector
只是一个指针,没有真正的循环依赖。
您可以使用继承:
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";
}
std::map
/std::set
。这正是我四周前所做的。 - Lightness Races in Orbit使用类型级不动点运算符。
#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}}};
}
ScriptParameter
内任意嵌套向量。(本质上,我们是在说脚本参数既可以是单个值,也可以是整个值的森林。) 将定义分为两部分可能会更好:// 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>>;
或者,如果这里的目标是将参数定义为一组选择加上这些相同选择的向量,那么可以尝试一些模板魔法:
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>>;
ScriptParameter
理解为什么?类型还是前向声明的类? - Jonathan Mee