正在进行中。这种方法的优点是在进行赋值时不需要转换任何内容,或者下面列出的任何功能。
目前它可以:
- 存储非容器字面类型(const char*、double、int、float、char、bool)
- 使用ostream运算符输出相应键的值
- 重新分配现有键的值
- 仅使用append方法添加新的键值对,键不能相同,否则会得到错误消息
- 使用+运算符添加相同类型的字面量
在代码中,我已经在主函数中演示了它目前能做什么。
#include <vector>
#include <any>
#include <utility>
#include <iostream>
using namespace std;
class ArbMap
{
public:
ArbMap() : vec({}), None("None") {}
ArbMap(const vector < pair<any,any> > &x)
: vec(x), None("None") {}
void elem(any &x, string &temp, int num=0 )
{
try
{
switch (num)
{
case 0:
any_cast<int>(x);
temp = "i";
break;
case 1:
any_cast<double>(x);
temp = "d";
break;
case 2:
any_cast<const char*>(x);
temp = "cc";
break;
case 3:
any_cast<char>(x);
temp = "c";
break;
case 4:
any_cast<bool>(x);
temp = "b";
break;
case 5:
any_cast<string>(x);
temp = "s";
break;
}
}
catch(const bad_cast& e)
{
elem(x,temp,++num);
}
}
size_t size()
{
return vec.size();
}
any& operator[](any key)
{
ArbMap temp;
string stemp;
for (size_t i = 0; i<vec.size(); ++i)
{
temp.elem(vec[i].first,stemp);
if (stemp=="i")
{
try
{
any_cast<int>(key);
}
catch(const bad_cast& e)
{
continue;
}
if (any_cast<int>(key)==any_cast<int>(vec[i].first))
{
return vec[i].second;
}
}
else if (stemp=="d")
{
try
{
any_cast<double>(key);
}
catch(const bad_cast& e)
{
continue;
}
if (any_cast<double>(key)==any_cast<double>(vec[i].first))
{
return vec[i].second;
}
}
else if (stemp=="cc")
{
try
{
any_cast<const char*>(key);
}
catch(const bad_cast& e)
{
continue;
}
if (any_cast<const char*>(key)==any_cast<const char*>(vec[i].first))
{
return vec[i].second;
}
}
else if (stemp=="c")
{
try
{
any_cast<char>(key);
}
catch(const bad_cast& e)
{
continue;
}
if (any_cast<char>(key)==any_cast<char>(vec[i].first))
{
return vec[i].second;
}
}
else if (stemp=="b")
{
try
{
any_cast<bool>(key);
}
catch(const bad_cast& e)
{
continue;
}
if (any_cast<bool>(key)==any_cast<bool>(vec[i].first))
{
return vec[i].second;
}
}
}
throw -1;
}
void print();
void append(any key, any value);
private:
vector < pair<any,any> > vec;
any None;
};
ostream& operator<<(ostream& out, any a)
{
ArbMap temp;
string stemp;
temp.elem(a,stemp);
if (stemp=="i") out << any_cast<int>(a);
else if (stemp=="d") out << any_cast<double>(a);
else if (stemp=="cc") out << any_cast<const char*>(a);
else if (stemp=="c") out << any_cast<char>(a);
else if (stemp=="b")
{
if (any_cast<bool>(a)==1)
out << "true";
else
out << "false";
}
else if (stemp=="s") out << any_cast<string>(a);
return out;
}
any operator+(any val1, any val2)
{
ArbMap temp;
string stemp1, stemp2;
temp.elem(val1,stemp1);
temp.elem(val2,stemp2);
try
{
if (stemp1 != stemp2)
throw -1;
if (stemp1 == "i")
{
return any_cast<int>(val1)+any_cast<int>(val2);
}
else if (stemp1 == "d")
{
return any_cast<double>(val1)+any_cast<double>(val2);
}
else if (stemp1 == "cc")
{
return string(any_cast<const char*>(val1))+string(any_cast<const char*>(val2));
}
else if (stemp1 == "c")
{
return string{any_cast<char>(val1)}+string{any_cast<char>(val2)};
}
else if (stemp1=="b")
{
return static_cast<bool>(any_cast<bool>(val1)+any_cast<bool>(val2));
}
}
catch (int err)
{
cout << "Bad cast! Operands must be of the same 'type'.\n";
}
return val1;
}
void ArbMap::print()
{
cout << '\n';
for (size_t i = 0; i<vec.size(); ++i)
{
cout << vec[i].first << ": " << vec[i].second << '\n';
}
cout << '\n';
}
void ArbMap::append(any key, any value)
{
try
{
(*this)[key];
throw "Already exists!";
}
catch(int error)
{
vec.push_back({key,value});
}
catch(const char* error)
{
cout << "ArbMap::append failed, key already exists!\n";
}
}
int main() {
ArbMap s({{1,2},{"aaa",1.2},{'c',33.3},{"what","this is awesome"}, {true, false}});
cout << s[1] << '\n' << s["aaa"] << '\n' << s['c']
<< '\n' << s["what"] << '\n'
<< s[true] << '\n';
s.print();
s[1] = "hello";
s.print();
s.append(2.3,"what");
s.print();
s[2.3] = "hello";
s.print();
s.append(2.3,"what");
s.print();
s[1] = 1.2;
s.print();
s.append(2.4,1.2);
cout << s[1]+s[2.4] << '\n';
cout << s["what"] + s[2.3] << '\n';
s.append('d','a');
cout << s['c'] << '\n';
cout << s[2.4]+ s["aaa"]+ s['c'] + s['c'] + s['c'] << '\n';
cout << s[true]+s[true] << '\n';
return 0;
}
boost::any
。 - chrisstd::map<std::string, std::shared_ptr<void>>
。 - Bill Lynchvoid*
(shared_ptr<void>
是相同的)。你需要至少一个额外值来确定那个东西是什么。除非你在编写真正低级别的代码,否则我会使用指向基类的指针或boost::variant<>
(如果不可用)。 - BlindyMyField<T>
,我想另一个选项是一个基类,每个MyField<T>
都继承自该基类。 - chris