我想要一个包含对不同类型变量的引用的地图。为此,我使用std::variant
这样:
using foo = std::variant<std::atomic<double> &, std::atomic<int> &, std::string &>;
这与gcc 7.3.0编译得那么远。使用的编译器标志:-Wall -Wextra -Werror -O3 -std=c++17
添加此代码:
using ServerParameter = struct ServerParameter
{
foo myVariants; <---- gcc error
bool someLogic;
};
打破了代码,我得到了这个gcc错误:
错误:静态断言失败:变量必须没有引用 备选
我的意图是这样的 - 但目前我不能,因为using
的{{1}}已经失败:
ServerParameter
我可以很好地处理auto bar() -> void
{
std::atomic<double> atom_double;
std::atomic<int> atom_int;
std::string myString;
...
std::map<std::string, ServerParameter> variableList(
{
{ {"SomeText1" }, { atom_double; true } },
{ {"SomeText2" }, { atom_int; true } },
{ {"SomeText3" }, { myString; false } },
}
);
...
}
中的项目 - 具体取决于引用的类型 - variableList
。
注意:
std::visit
工作而不是pointer
,e.q。:
reference
然后是非常优雅的using foo = std::variant<std::atomic<double> *, std::atomic<int> *, std::string *>;
auto bar() -> void
{
std::atomic<double> atom_double;
std::atomic<int> atom_int;
std::string myString;
...
std::map<std::string, ServerParameter> variableList(
{
{ {"SomeText1" }, { &atom_double; true } },
{ {"SomeText2" }, { &atom_int; true } },
{ {"SomeText3" }, { &myString; false } },
}
);
...
}
:
std::visit
我的问题:
std::visit( visitHandler
{
[&](std::atomic<double> * enumType) { *enumType = ..an assignment..; },
[&](std::atomic<int> * enumType) { *enumType = ..an assignment..; },
[&](FaF::string * enumType) { *enumType = ..an assignment..; },
}, variantEntry );
答案 0 :(得分:4)
不允许变体保存引用,数组或类型 无效。空变体也是格式不正确的(
std::variant<std::monostate>
可以代替使用。)
所以使用指针代替是正确的。
答案 1 :(得分:0)
需要注意的是 boost::variant<>
允许保存引用。所以考虑继续前进。
一个不错的 MWE:
#include "boost/variant.hpp"
#include <iostream>
class my_visitor : public boost::static_visitor<int>
{
public:
int operator() (int & i) const
{
return i;
}
int operator() (const std::string & str) const
{
return str.length();
}
};
int main()
{
std::string mystr = "hello world";
boost::variant<int &, std::string &> u(mystr);
std::cout << u; // output: hello world
int result = boost::apply_visitor(my_visitor(), u);
std::cout << result; // output: 11 (i.e., length of "hello world")
}