我们可以明确地对可以存储在boost varaint中的值进行类型转换吗?
例:
typedef int abc;
typedef int asd;
typedef boost::variant<abc, char, asd, float> link_try1;
int main()
{
link_try1 qw;
qw = static_cast<asd>(1234);
printf("value of which is:%d", qw.which());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在这里,我希望which()函数重新启动3但它总是重新生成0.有没有办法直接更改其中的值_(类变量中的私有变量)或显式指定要使用的数据类型?
关心Ankith
尝试在没有基类和虚拟调用的情况下获取编译时方法和对象选择.
情况如下:
struct A {
void f1()const { cout << "A::f1" << endl;}
void f2()const { cout << "A::f2" << endl;}
};
struct B {
void f1()const { cout << "B::f1" << endl;}
void f2()const { cout << "B::f2" << endl;}
};
class Holder {
A* _a = nullptr;
B* _b = nullptr;
public:
Holder(A* a): _a(a) {}
Holder(B* b): _b(b) {}
void f1()const {
if(_a) _a->f1();
else if(_b) _b->f1();
}
void f2()const {
if(_a) _a->f2();
else if(_b) _b->f2();
} …Run Code Online (Sandbox Code Playgroud) 我需要在c ++中存储一组int和double(表示名义和实数值).我显然可以将它们全部存储在一起std::vector<double>,但这感觉有点不对,并没有获得美学奖励积分.
我也可以基于多态来烹饪一些东西,但我也需要集合非常有效:存储和检索集合中的数据应该尽可能快.我发现很难判断这样的解决方案是否最有效.
我还发现了boost :: variant,这可能会有所帮助.
附加信息:集合中的项目数量很少(<100),并在初始化集合时已知.
总结:我显然可以通过无数种方式解决这个问题,但我不确定在(i)效率非常重要和(ii)我还想编写一些不错的代码时,什么是一个好的解决方案.我最好的选择是什么?
编辑,附加信息:集合表示较大数据集中的"行",其元素表示某些"列"的值.行的属性是已知的,因此知道在哪个位置存储什么类型的数据.我所讨论的'效率'主要是检索某列的int/double值的效率,尽管快速设置值也很重要.我有一些函数可以对需要尽快检索的数据进行操作.例:
typedef std::vector<double> Row;
void doubleFun(Row const &row)
{
// Function knows there's always a double at index 0
double value = row[0];
...
}
void integerFun(Row const &row)
{
// Function knows there's always an integer at index 1
int value = row[1];
...
}
Run Code Online (Sandbox Code Playgroud)
经过一番思考和阅读建议到目前为止,似乎只是将int列和双列存储在两个单独的向量中是一个可靠的解决方案.Row然后,该集合可以定义两个不同的成员,用于检索函数可以使用的名义和实际数据.
vector<double>我想,只是存储为一个没问题,但这取决于double和int之间的转换速度有多快(这可能相当令人印象深刻).
抱歉一开始有点不清楚,我希望现在更清楚了,我可以对此事有更多的想法.
std::vector< boost::variant<std::string, int> > vec;
std::string s1("abacus");
int i1 = 42;
vec.push_back(s1);
vec.push_back(i1);
std::cout << vec.at(0).size() << "\n";
Run Code Online (Sandbox Code Playgroud)
当我尝试运行此代码时,我收到以下错误:
main.cpp:68: error: ‘class boost::variant<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>’ has no member named ‘size’
make: *** [main.o] Error 1
Run Code Online (Sandbox Code Playgroud)
但是,作为一个字符串,它应该有一个size()方法.我不确定出了什么问题.注意用最后一行替换:
std::cout << vec.at(0) << "\n";
Run Code Online (Sandbox Code Playgroud)
将按预期打印"算盘".
Windows 7 64位上的Visual Studio Enterprise 2010 sp1.提升1.48.0.
这里开始相关代码.这些位在标题中定义.
//typedef struct {} empty_t;
//typedef std::pair<size_t, std::shared_ptr<char>> string_t; //Don't ask...
//typedef boost::variant<empty_t, long, double, some other PODs, string_t> variant_t;
//typedef std::map<unsigned short, variant_t> variant_map_t;
Run Code Online (Sandbox Code Playgroud)
这是在复制构造函数的主体中:
std::for_each(std::begin(incoming.values_), std::end(incoming.values_), [&](variant_map_t::value_type value)
{
// This guy is going to populate this::values_, doing the right thing -
// copying by value native and POD types, or deep copying pointers.
boost::apply_visitor(deep_copy_visitor(*this, value.first), value.second);
});
Run Code Online (Sandbox Code Playgroud)
我找到的错误是lambda的参数列表.交换被调用,我觉得在对的拷贝构造函数,试图从传递到拉姆达的参数右值先分配.编译器认为"value.first"在std :: pair复制构造函数中被赋值时是const.但显然,参数不是const限定的,mapped_type或key_type不是const限定的,复制构造函数不是const方法,并且没有任何关系.
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\utility(209) : see reference to …Run Code Online (Sandbox Code Playgroud) 我是否需要使用诸如class Visitor : public boost::static_visitor<>boost :: variant之类的访问者类?
如果没有,有没有理由不使用访客?是否有理由喜欢访客班?
我问这个问题,因为访问者类似乎是使用boost :: variant的一个多余方面.
我正在尝试使用boost :: static_visitor在boost :: variant类型上实现影响某些变量状态的操作.我的方法是在命令访问者类中包含所有状态变量,但似乎这是不可能的.
这是我的代码示例:
#include <string>
#include <sstream>
#include <vector>
#include <boost/variant.hpp>
#include <boost/foreach.hpp>
struct TypeA
{
int varA;
int varB;
};
struct TypeB
{
std::string varA;
std::string varB;
};
typedef boost::variant<TypeA, TypeB> MyVariantType;
class MyCommandVisitor : public boost::static_visitor<>
{
public:
//These are just examples, the actions only need to be able to touch
// internal variables.
void operator()(TypeA & t) const
{
m_runningSum += t.varA;
m_outStream << "TYPEA ACTION: " << t.varB << std::endl;
}
void operator(TypeB …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用boost :: variant和boost :: apply_visitor.这已经有效了,除非我试图让Vistor的函数返回一个(布尔值).我在SO上做了很多这样的例子,但我无法创建一个工作样本.这是我的代码没有返回值:
#include <iostream>
#include <boost/variant.hpp>
#include <string>
#include <conio.h>
class CnVisitor : public boost::static_visitor<>
{
public:
void operator()(double& valueFloat ) const
{
std::cout << (double)valueFloat;
}
void operator()(std::string& valueString ) const
{
std::cout << valueString.c_str ();
}
};
int main()
{
std::vector< boost::variant< double, std::string >> vec;
vec.push_back((double)1.423423);
vec.push_back((std::string)"some text");
CnVisitor l_Visitor;
for ( int i = 0; i < vec.size (); ++i )
{
boost::apply_visitor ( l_Visitor, vec[i] );
}
_getch ();
}
Run Code Online (Sandbox Code Playgroud) 我想创建一个适用于多种类型的类.然而,我想要实例化这个类的元素,而不是使用类型,而是使用字符串(例如,使用"int"而不是int),这样我就不必在使用这个类时使用大量的调度程序函数.
在一个小班上Tab,我尝试了两个"解决方案":
第一个:
template <typename T>
class Tab {
public :
Tab(std::size_t length) {
T* tab_[length];
tab = tab_;
}
T* tab;
T operator[](std::size_t i) {
return tab[i];
}
};
Tab getTab(std::string type, std::size_t length) {
if (type == "int") {
Tab<int> tab(length);
} else if (type == "double") {
Tab<double> tab(length);
}
return tab;
}
Run Code Online (Sandbox Code Playgroud)
第二个:
typedef boost::variant<int, double> numeric;
typedef boost::variant<int*, double*> numeric_ptr;
class Tab {
public :
Tab(std::string type, std::size_t length) …Run Code Online (Sandbox Code Playgroud) 在Java中,我能够在不指定类型的情况下定义泛型类的变量.
class Tree<T extends Comparable<? super T>> {}
somewhere-else: Tree tree;
Run Code Online (Sandbox Code Playgroud)
然后我可以从文件中读取一些对象并将其类型转换为我想要的类类型.
tree = (Tree<String>) some object;
Run Code Online (Sandbox Code Playgroud)
随着boost::variant我已经开始变体的定义.
typedef boost::variant<Tree<std::string>, Tree<int>> TreeVariant; TreeVariant tree;
Run Code Online (Sandbox Code Playgroud)
我知道我需要指定一个visitor class但是从这个例子中不清楚如何定义它,以便我能够分配给我的tree变量Tree<std::string>或者Tree<int>.
然后我想从那里继续使用变量调用Tree的成员函数tree.
我有一个有模板的类:
template<class T = int> class slider;
Run Code Online (Sandbox Code Playgroud)
该类有一个void Process(void)方法,所以,我认为它应该是可调用的类型,返回值是无效的,并且没有参数.
至于现在我有这个代码来调用我的应用程序中的每个帧的进程:
//class menu:
typedef boost::variant<std::shared_ptr<slider<int>>,std::shared_ptr<slider<float>>,std::shared_ptr<slider<double>>,std::shared_ptr<slider<char>>> slider_type;
std::map<std::string,slider_type> Sliders;
//buttons ... etc ...
void Process()
{
if(!Sliders.empty())
{
for(auto i = Sliders.begin(); i != Sliders.end(); ++i)
{
switch(i->second.which())
{
case 0://slider<int>
{
boost::get<std::shared_ptr<slider<int>>>(i->second)->Process();
break;
}
case 1://slider<float>
{
boost::get<std::shared_ptr<slider<float>>>(i->second)->Process();
break;
}
//.....
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
是否可以执行函数Process(),如下例所示?
for(auto i = Sliders.begin(); i != Sliders.end(); ++i)
{
switch(i->second.which())
{
boost::get<???Any???>(i->second)->Process();
}
}
Run Code Online (Sandbox Code Playgroud)
如果有,怎么样?
我已经读过boost::variant如果它的所有变体都是可流动的,那么它是可流动的.然而,
#include <iostream>
#include <vector>
#include <string>
#include <boost/variant.hpp>
std::ostream& operator<<(std::ostream& out, const std::vector<int>& v) {
for(int i = 0; i < v.size(); ++i)
out << " " << v[i];
return out;
}
int main() {
boost::variant<int, std::string > a(3);
std::cout << a << '\n'; // OK
std::vector<int> b(3, 1);
std::cout << b << '\n'; // OK
boost::variant<int, std::vector<int> > c(3);
std::cout << c << '\n'; // ERROR
}
Run Code Online (Sandbox Code Playgroud)
无法编译.为什么?
版本:
boost-variant ×12
c++ ×12
boost ×4
c++11 ×2
templates ×2
collections ×1
lambda ×1
macros ×1
visual-c++ ×1